diff options
401 files changed, 5840 insertions, 3348 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 5a06011246f..b53c6f6b71f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -186,11 +186,11 @@ unset(PLATFORM_DEFAULT) # Modifiers -option(WITH_MOD_FLUID "Enable Elbeem Modifier (Fluid Simulation)" ON) -option(WITH_MOD_SMOKE "Enable Smoke Modifier (Smoke Simulation)" ON) -option(WITH_MOD_BOOLEAN "Enable Boolean Modifier" ON) -option(WITH_MOD_REMESH "Enable Remesh Modifier" ON) -option(WITH_MOD_CLOTH_ELTOPO "Enable Experimental cloth solver" OFF) +option(WITH_MOD_FLUID "Enable Elbeem Modifier (Fluid Simulation)" ON) +option(WITH_MOD_SMOKE "Enable Smoke Modifier (Smoke Simulation)" ON) +option(WITH_MOD_BOOLEAN "Enable Boolean Modifier" ON) +option(WITH_MOD_REMESH "Enable Remesh Modifier" ON) +option(WITH_MOD_CLOTH_ELTOPO "Enable Experimental cloth solver" OFF) mark_as_advanced(WITH_MOD_CLOTH_ELTOPO) option(WITH_MOD_OCEANSIM "Enable Ocean Modifier" OFF) @@ -658,11 +658,7 @@ if(UNIX AND NOT APPLE) else() set(Boost_USE_MULTITHREADED ON) endif() - if(WITH_CYCLES_OSL) - find_package(Boost 1.34 COMPONENTS filesystem python3 regex system thread) # osl_nodes uses boost_python - else() - find_package(Boost 1.34 COMPONENTS filesystem regex system thread) - endif() + find_package(Boost 1.34 COMPONENTS filesystem regex system thread) mark_as_advanced(Boost_DIR) # why doesnt boost do this? endif() @@ -828,7 +824,7 @@ if(UNIX AND NOT APPLE) elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang") set(PLATFORM_CFLAGS "-pipe -fPIC -funsigned-char -fno-strict-aliasing") # Solaris CC - elseif(CMAKE_CXX_COMPILER_ID MATCHES "SunPro") + elseif(CMAKE_CXX_COMPILER_ID MATCHES "SunPro") set(PLATFORM_CFLAGS "-pipe -features=extensions -fPIC -D__FUNCTION__=__func__") # Intel C++ Compiler @@ -1137,12 +1133,6 @@ elseif(WIN32) debug libboost_date_time-${BOOST_DEBUG_POSTFIX} debug libboost_filesystem-${BOOST_DEBUG_POSTFIX} debug libboost_regex-${BOOST_DEBUG_POSTFIX} debug libboost_system-${BOOST_DEBUG_POSTFIX} debug libboost_thread-${BOOST_DEBUG_POSTFIX}) - if(WITH_CYCLES_OSL) - set(BOOST_LIBRARIES ${BOOST_LIBRARIES} - optimized libboost_python3-${BOOST_POSTFIX} - debug libboost_python3-${BOOST_DEBUG_POSTFIX}) - endif(WITH_CYCLES_OSL) - set(BOOST_DEFINITIONS "-DBOOST_ALL_NO_LIB") endif() @@ -1323,12 +1313,6 @@ elseif(WIN32) debug boost_date_time-${BOOST_DEBUG_POSTFIX} boost_filesystem-${BOOST_DEBUG_POSTFIX} boost_regex-${BOOST_DEBUG_POSTFIX} boost_system-${BOOST_DEBUG_POSTFIX} boost_thread-${BOOST_DEBUG_POSTFIX}) - if(WITH_CYCLES_OSL) - set(BOOST_LIBRARIES ${BOOST_LIBRARIES} - optimized libboost_python3-${BOOST_POSTFIX} - debug libboost_python3-${BOOST_DEBUG_POSTFIX}) - endif(WITH_CYCLES_OSL) - set(BOOST_LIBPATH ${BOOST}/lib) set(BOOST_DEFINITIONS "-DBOOST_ALL_NO_LIB -DBOOST_THREAD_USE_LIB ") endif() @@ -1583,11 +1567,7 @@ elseif(APPLE) if(WITH_BOOST) set(BOOST ${LIBDIR}/boost) set(BOOST_INCLUDE_DIR ${BOOST}/include) - if(WITH_CYCLES_OSL) - set(BOOST_LIBRARIES boost_date_time-mt boost_filesystem-mt boost_python3-mt boost_regex-mt boost_system-mt boost_thread-mt) - else(WITH_CYCLES_OSL) - set(BOOST_LIBRARIES boost_date_time-mt boost_filesystem-mt boost_regex-mt boost_system-mt boost_thread-mt) - endif(WITH_CYCLES_OSL) + set(BOOST_LIBRARIES boost_date_time-mt boost_filesystem-mt boost_regex-mt boost_system-mt boost_thread-mt) set(BOOST_LIBPATH ${BOOST}/lib) set(BOOST_DEFINITIONS) endif() diff --git a/build_files/buildbot/config/user-config-glibc211-i686.py b/build_files/buildbot/config/user-config-glibc211-i686.py index d608c6c2e4a..23ab87a6ba3 100644 --- a/build_files/buildbot/config/user-config-glibc211-i686.py +++ b/build_files/buildbot/config/user-config-glibc211-i686.py @@ -37,7 +37,7 @@ BF_FFMPEG_LIB_STATIC = '${BF_FFMPEG_LIBPATH}/libavformat.a ${BF_FFMPEG_LIBPATH}/ '${BF_FFMPEG_LIBPATH}/libswscale.a ${BF_FFMPEG_LIBPATH}/libswresample.a ' + \ '/usr/lib/libxvidcore.a /usr/lib/libx264.a /usr/lib/libmp3lame.a /usr/lib/libvpx.a /usr/lib/libvorbis.a ' + \ '/usr/lib/libogg.a /usr/lib/libvorbisenc.a /usr/lib/libtheora.a /usr/lib/libschroedinger-1.0.a ' + \ - '/usr/lib/liborc-0.4.a /usr/lib/libasound.a' + '/usr/lib/liborc-0.4.a' # Don't depend on system's libstdc++ WITH_BF_STATICCXX = True diff --git a/build_files/buildbot/config/user-config-glibc211-x86_64.py b/build_files/buildbot/config/user-config-glibc211-x86_64.py index 62da39f3757..84899cc3848 100644 --- a/build_files/buildbot/config/user-config-glibc211-x86_64.py +++ b/build_files/buildbot/config/user-config-glibc211-x86_64.py @@ -37,7 +37,7 @@ BF_FFMPEG_LIB_STATIC = '${BF_FFMPEG_LIBPATH}/libavformat.a ${BF_FFMPEG_LIBPATH}/ '${BF_FFMPEG_LIBPATH}/libswscale.a ${BF_FFMPEG_LIBPATH}/libswresample.a ' + \ '/usr/lib/libxvidcore.a /usr/lib/libx264.a /usr/lib/libmp3lame.a /usr/lib/libvpx.a /usr/lib/libvorbis.a ' + \ '/usr/lib/libogg.a /usr/lib/libvorbisenc.a /usr/lib/libtheora.a /usr/lib/libschroedinger-1.0.a ' + \ - '/usr/lib/liborc-0.4.a /usr/lib/libasound.a' + '/usr/lib/liborc-0.4.a' # Don't depend on system's libstdc++ WITH_BF_STATICCXX = True diff --git a/build_files/buildbot/config/user-config-player-glibc211-i686.py b/build_files/buildbot/config/user-config-player-glibc211-i686.py index d02e527ee9f..3ac061d934f 100644 --- a/build_files/buildbot/config/user-config-player-glibc211-i686.py +++ b/build_files/buildbot/config/user-config-player-glibc211-i686.py @@ -23,7 +23,7 @@ BF_FFMPEG_LIB_STATIC = '${BF_FFMPEG_LIBPATH}/libavformat.a ${BF_FFMPEG_LIBPATH}/ '${BF_FFMPEG_LIBPATH}/libswscale.a ${BF_FFMPEG_LIBPATH}/libswresample.a ' + \ '/usr/lib/libxvidcore.a /usr/lib/libx264.a /usr/lib/libmp3lame.a /usr/lib/libvpx.a /usr/lib/libvorbis.a ' + \ '/usr/lib/libogg.a /usr/lib/libvorbisenc.a /usr/lib/libtheora.a /usr/lib/libschroedinger-1.0.a ' + \ - '/usr/lib/liborc-0.4.a /usr/lib/libasound.a' + '/usr/lib/liborc-0.4.a' # Don't depend on system's libstdc++ WITH_BF_STATICCXX = True diff --git a/build_files/buildbot/config/user-config-player-glibc211-x86_64.py b/build_files/buildbot/config/user-config-player-glibc211-x86_64.py index ba7dae2f6d6..08d277edb7b 100644 --- a/build_files/buildbot/config/user-config-player-glibc211-x86_64.py +++ b/build_files/buildbot/config/user-config-player-glibc211-x86_64.py @@ -23,7 +23,7 @@ BF_FFMPEG_LIB_STATIC = '${BF_FFMPEG_LIBPATH}/libavformat.a ${BF_FFMPEG_LIBPATH}/ '${BF_FFMPEG_LIBPATH}/libswscale.a ${BF_FFMPEG_LIBPATH}/libswresample.a ' + \ '/usr/lib/libxvidcore.a /usr/lib/libx264.a /usr/lib/libmp3lame.a /usr/lib/libvpx.a /usr/lib/libvorbis.a ' + \ '/usr/lib/libogg.a /usr/lib/libvorbisenc.a /usr/lib/libtheora.a /usr/lib/libschroedinger-1.0.a ' + \ - '/usr/lib/liborc-0.4.a /usr/lib/libasound.a' + '/usr/lib/liborc-0.4.a' # Don't depend on system's libstdc++ WITH_BF_STATICCXX = True diff --git a/build_files/buildbot/slave_compile.py b/build_files/buildbot/slave_compile.py index 3d8679d6f74..bedada93a5a 100644 --- a/build_files/buildbot/slave_compile.py +++ b/build_files/buildbot/slave_compile.py @@ -81,6 +81,12 @@ else: elif builder.endswith('linux_glibc27_i386_scons'): configs = ['user-config-player-glibc27-i686.py', 'user-config-glibc27-i686.py'] + if builder.endswith('linux_glibc211_x86_64_scons'): + configs = ['user-config-player-glibc211-x86_64.py', + 'user-config-glibc211-x86_64.py'] + elif builder.endswith('linux_glibc211_i386_scons'): + configs = ['user-config-player-glibc211-i686.py', + 'user-config-glibc211-i686.py'] for config in configs: config_fpath = os.path.join(config_dir, config) diff --git a/build_files/buildbot/slave_pack.py b/build_files/buildbot/slave_pack.py index f8d59b5a609..b7775ef872f 100644 --- a/build_files/buildbot/slave_pack.py +++ b/build_files/buildbot/slave_pack.py @@ -63,6 +63,12 @@ if builder.find('scons') != -1: elif builder.endswith('linux_glibc27_i386_scons'): config = 'user-config-glibc27-i686.py' bits = 32 + if builder.endswith('linux_glibc211_x86_64_scons'): + config = 'user-config-glibc211-x86_64.py' + bits = 64 + elif builder.endswith('linux_glibc211_i386_scons'): + config = 'user-config-glibc211-i686.py' + bits = 32 if config is not None: config_fpath = os.path.join(config_dir, config) diff --git a/build_files/scons/tools/btools.py b/build_files/scons/tools/btools.py index df9c908441e..19652bb7851 100644 --- a/build_files/scons/tools/btools.py +++ b/build_files/scons/tools/btools.py @@ -662,11 +662,16 @@ def buildslave(target=None, source=None, env=None): if platform == 'linux': import platform + if env['BF_INSTALLDIR'].find('glibc27') != -1: + glibc="glibc27" + elif env['BF_INSTALLDIR'].find('glibc211') != -1: + glibc="glibc211" + bitness = platform.architecture()[0] if bitness == '64bit': - platform = 'linux-glibc27-x86_64' + platform = 'linux-' + glibc + '-x86_64' elif bitness == '32bit': - platform = 'linux-glibc27-i686' + platform = 'linux-' + glibc + '-i686' if platform == 'darwin': platform = 'OSX-' + env['MACOSX_ARCHITECTURE'] diff --git a/doc/python_api/sphinx_doc_gen.py b/doc/python_api/sphinx_doc_gen.py index bd2f3e8e3bf..a8e2275e1ae 100644 --- a/doc/python_api/sphinx_doc_gen.py +++ b/doc/python_api/sphinx_doc_gen.py @@ -918,6 +918,72 @@ def pymodule2sphinx(basepath, module_name, module, title): file.close() +# Changes in blender will force errors here +context_type_map = { + "active_base": ("ObjectBase", False), + "active_bone": ("EditBone", False), + "active_object": ("Object", False), + "active_operator": ("Operator", False), + "active_pose_bone": ("PoseBone", False), + "active_node": ("Node", False), + "armature": ("Armature", False), + "bone": ("Bone", False), + "brush": ("Brush", False), + "camera": ("Camera", False), + "cloth": ("ClothModifier", False), + "collision": ("CollisionModifier", False), + "curve": ("Curve", False), + "dynamic_paint": ("DynamicPaintModifier", False), + "edit_bone": ("EditBone", False), + "edit_image": ("Image", False), + "edit_mask": ("Mask", False), + "edit_movieclip": ("MovieClip", False), + "edit_object": ("Object", False), + "edit_text": ("Text", False), + "editable_bones": ("EditBone", True), + "fluid": ("FluidSimulationModifier", False), + "image_paint_object": ("Object", False), + "lamp": ("Lamp", False), + "lattice": ("Lattice", False), + "material": ("Material", False), + "material_slot": ("MaterialSlot", False), + "mesh": ("Mesh", False), + "meta_ball": ("MetaBall", False), + "object": ("Object", False), + "particle_edit_object": ("Object", False), + "particle_settings": ("ParticleSettings", False), + "particle_system": ("ParticleSystem", False), + "particle_system_editable": ("ParticleSystem", False), + "pose_bone": ("PoseBone", False), + "scene": ("Scene", False), + "sculpt_object": ("Object", False), + "selectable_bases": ("ObjectBase", True), + "selectable_objects": ("Object", True), + "selected_bases": ("ObjectBase", True), + "selected_bones": ("EditBone", True), + "selected_editable_bases": ("ObjectBase", True), + "selected_editable_bones": ("EditBone", True), + "selected_editable_objects": ("Object", True), + "selected_editable_sequences": ("Sequence", True), + "selected_nodes": ("Node", True), + "selected_objects": ("Object", True), + "selected_pose_bones": ("PoseBone", True), + "selected_sequences": ("Sequence", True), + "sequences": ("Sequence", True), + "smoke": ("SmokeModifier", False), + "soft_body": ("SoftBodyModifier", False), + "speaker": ("Speaker", False), + "texture": ("Texture", False), + "texture_slot": ("MaterialTextureSlot", False), + "texture_user": ("ID", False), + "vertex_paint_object": ("Object", False), + "visible_bases": ("ObjectBase", True), + "visible_bones": ("EditBone", True), + "visible_objects": ("Object", True), + "visible_pose_bones": ("PoseBone", True), + "weight_paint_object": ("Object", False), + "world": ("World", False), +} def pycontext2sphinx(basepath): # Only use once. very irregular @@ -946,72 +1012,6 @@ def pycontext2sphinx(basepath): "sequencer_context_dir", ) - # Changes in blender will force errors here - type_map = { - "active_base": ("ObjectBase", False), - "active_bone": ("Bone", False), - "active_object": ("Object", False), - "active_operator": ("Operator", False), - "active_pose_bone": ("PoseBone", False), - "active_node": ("Node", False), - "armature": ("Armature", False), - "bone": ("Bone", False), - "brush": ("Brush", False), - "camera": ("Camera", False), - "cloth": ("ClothModifier", False), - "collision": ("CollisionModifier", False), - "curve": ("Curve", False), - "dynamic_paint": ("DynamicPaintModifier", False), - "edit_bone": ("EditBone", False), - "edit_image": ("Image", False), - "edit_mask": ("Mask", False), - "edit_movieclip": ("MovieClip", False), - "edit_object": ("Object", False), - "edit_text": ("Text", False), - "editable_bones": ("EditBone", True), - "fluid": ("FluidSimulationModifier", False), - "image_paint_object": ("Object", False), - "lamp": ("Lamp", False), - "lattice": ("Lattice", False), - "material": ("Material", False), - "material_slot": ("MaterialSlot", False), - "mesh": ("Mesh", False), - "meta_ball": ("MetaBall", False), - "object": ("Object", False), - "particle_edit_object": ("Object", False), - "particle_settings": ("ParticleSettings", False), - "particle_system": ("ParticleSystem", False), - "particle_system_editable": ("ParticleSystem", False), - "pose_bone": ("PoseBone", False), - "scene": ("Scene", False), - "sculpt_object": ("Object", False), - "selectable_bases": ("ObjectBase", True), - "selectable_objects": ("Object", True), - "selected_bases": ("ObjectBase", True), - "selected_bones": ("Bone", True), - "selected_editable_bases": ("ObjectBase", True), - "selected_editable_bones": ("Bone", True), - "selected_editable_objects": ("Object", True), - "selected_editable_sequences": ("Sequence", True), - "selected_nodes": ("Node", True), - "selected_objects": ("Object", True), - "selected_pose_bones": ("PoseBone", True), - "selected_sequences": ("Sequence", True), - "sequences": ("Sequence", True), - "smoke": ("SmokeModifier", False), - "soft_body": ("SoftBodyModifier", False), - "speaker": ("Speaker", False), - "texture": ("Texture", False), - "texture_slot": ("MaterialTextureSlot", False), - "texture_user": ("ID", False), - "vertex_paint_object": ("Object", False), - "visible_bases": ("ObjectBase", True), - "visible_bones": ("Object", True), - "visible_objects": ("Object", True), - "visible_pose_bones": ("PoseBone", True), - "weight_paint_object": ("Object", False), - "world": ("World", False), - } unique = set() blend_cdll = ctypes.CDLL("") @@ -1026,7 +1026,7 @@ def pycontext2sphinx(basepath): while char_array[i] is not None: member = ctypes.string_at(char_array[i]).decode(encoding="ascii") fw(".. data:: %s\n\n" % member) - member_type, is_seq = type_map[member] + member_type, is_seq = context_type_map[member] fw(" :type: %s :class:`bpy.types.%s`\n\n" % ("sequence of " if is_seq else "", member_type)) unique.add(member) i += 1 @@ -1034,8 +1034,8 @@ def pycontext2sphinx(basepath): # generate typemap... # for member in sorted(unique): # print(' "%s": ("", False),' % member) - if len(type_map) > len(unique): - raise Exception("Some types are not used: %s" % str([member for member in type_map if member not in unique])) + if len(context_type_map) > len(unique): + raise Exception("Some types are not used: %s" % str([member for member in context_type_map if member not in unique])) else: pass # will have raised an error above @@ -1322,6 +1322,13 @@ def pyrna2sphinx(basepath): fw(".. hlist::\n") fw(" :columns: 2\n\n") + # context does its own thing + # "active_base": ("ObjectBase", False), + for ref_attr, (ref_type, ref_is_seq) in sorted(context_type_map.items()): + if ref_type == struct_id: + fw(" * :mod:`bpy.context.%s`\n" % ref_attr) + del ref_attr, ref_type, ref_is_seq + for ref in struct.references: ref_split = ref.split(".") if len(ref_split) > 2: diff --git a/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp b/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp index 12b6d2e4f38..a114d8b8a87 100644 --- a/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp +++ b/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp @@ -174,21 +174,34 @@ bool AUD_OpenALDevice::AUD_OpenALHandle::stop() if(!m_status) return false; - // AUD_XXX Create a reference of our own object so that it doesn't get - // deleted before the end of this function - AUD_Reference<AUD_OpenALHandle> This = this; - - if(m_status == AUD_STATUS_PLAYING) - m_device->m_playingSounds.remove(This); - else - m_device->m_pausedSounds.remove(This); + m_status = AUD_STATUS_INVALID; alDeleteSources(1, &m_source); if(!m_isBuffered) alDeleteBuffers(CYCLE_BUFFERS, m_buffers); - m_status = AUD_STATUS_INVALID; - return true; + for(AUD_HandleIterator it = m_device->m_playingSounds.begin(); it != m_device->m_playingSounds.end(); it++) + { + if(it->get() == this) + { + AUD_Reference<AUD_OpenALHandle> This = *it; + + m_device->m_playingSounds.erase(it); + + return true; + } + } + + for(AUD_HandleIterator it = m_device->m_pausedSounds.begin(); it != m_device->m_pausedSounds.end(); it++) + { + if(it->get() == this) + { + m_device->m_pausedSounds.erase(it); + return true; + } + } + + return false; } bool AUD_OpenALDevice::AUD_OpenALHandle::getKeep() diff --git a/intern/audaspace/intern/AUD_SoftwareDevice.cpp b/intern/audaspace/intern/AUD_SoftwareDevice.cpp index 14f0c6429e9..1fbd0ad82d2 100644 --- a/intern/audaspace/intern/AUD_SoftwareDevice.cpp +++ b/intern/audaspace/intern/AUD_SoftwareDevice.cpp @@ -277,22 +277,33 @@ bool AUD_SoftwareDevice::AUD_SoftwareHandle::stop() if(!m_status) return false; - // AUD_XXX Create a reference of our own object so that it doesn't get - // deleted before the end of this function - AUD_Reference<AUD_SoftwareHandle> This = this; + m_status = AUD_STATUS_INVALID; - if(m_status == AUD_STATUS_PLAYING) + for(AUD_HandleIterator it = m_device->m_playingSounds.begin(); it != m_device->m_playingSounds.end(); it++) { - m_device->m_playingSounds.remove(This); + if(it->get() == this) + { + AUD_Reference<AUD_SoftwareHandle> This = *it; + + m_device->m_playingSounds.erase(it); - if(m_device->m_playingSounds.empty()) - m_device->playing(m_device->m_playback = false); + if(m_device->m_playingSounds.empty()) + m_device->playing(m_device->m_playback = false); + + return true; + } } - else - m_device->m_pausedSounds.remove(This); - m_status = AUD_STATUS_INVALID; - return true; + for(AUD_HandleIterator it = m_device->m_pausedSounds.begin(); it != m_device->m_pausedSounds.end(); it++) + { + if(it->get() == this) + { + m_device->m_pausedSounds.erase(it); + return true; + } + } + + return false; } bool AUD_SoftwareDevice::AUD_SoftwareHandle::getKeep() diff --git a/intern/bsp/extern/CSG_BooleanOps.h b/intern/bsp/extern/CSG_BooleanOps.h index 94a74c30536..5ba6e0d76a1 100644 --- a/intern/bsp/extern/CSG_BooleanOps.h +++ b/intern/bsp/extern/CSG_BooleanOps.h @@ -61,9 +61,9 @@ extern "C" { #endif typedef struct { - int vertex_index[4]; - int vertex_number; - int orig_face; + int vertex_index[4]; + int vertex_number; + int orig_face; } CSG_IFace; /** @@ -72,7 +72,7 @@ typedef struct { */ typedef struct { - float position[3]; + float position[3]; } CSG_IVertex; /** diff --git a/intern/bsp/intern/BOP_CarveInterface.cpp b/intern/bsp/intern/BOP_CarveInterface.cpp index 1f9c989cbc8..93d15e6d5e6 100644 --- a/intern/bsp/intern/BOP_CarveInterface.cpp +++ b/intern/bsp/intern/BOP_CarveInterface.cpp @@ -135,10 +135,10 @@ static bool Carve_checkEdgeFaceIntersections(carve::csg::Intersections &intersec static inline bool Carve_facesAreCoplanar(const MeshSet<3>::face_t *a, const MeshSet<3>::face_t *b) { - carve::geom3d::Ray temp; - // XXX: Find a better definition. This may be a source of problems - // if floating point inaccuracies cause an incorrect answer. - return !carve::geom3d::planeIntersection(a->plane, b->plane, temp); + carve::geom3d::Ray temp; + // XXX: Find a better definition. This may be a source of problems + // if floating point inaccuracies cause an incorrect answer. + return !carve::geom3d::planeIntersection(a->plane, b->plane, temp); } static bool Carve_checkMeshSetInterseciton_do(carve::csg::Intersections &intersections, diff --git a/intern/container/CMakeLists.txt b/intern/container/CMakeLists.txt index 4743247af26..8adc46a59de 100644 --- a/intern/container/CMakeLists.txt +++ b/intern/container/CMakeLists.txt @@ -35,6 +35,8 @@ set(INC_SYS set(SRC CTR_HashedPtr.h CTR_Map.h + CTR_TaggedIndex.h + CTR_TaggedSetOps.h ) # infact nothing to compile! diff --git a/intern/cycles/SConscript b/intern/cycles/SConscript index a7b8637e3ad..c0e0353d37d 100644 --- a/intern/cycles/SConscript +++ b/intern/cycles/SConscript @@ -29,7 +29,7 @@ if env['WITH_BF_CYCLES_CUDA_BINARIES']: incs.extend('. bvh render device kernel kernel/osl kernel/svm util subd'.split()) incs.extend('#intern/guardedalloc #source/blender/makesrna #source/blender/makesdna'.split()) incs.extend('#source/blender/blenloader ../../source/blender/makesrna/intern'.split()) -incs.extend('#extern/glew/include'.split()) +incs.extend('#extern/glew/include #intern/mikktspace'.split()) incs.append(cycles['BF_OIIO_INC']) incs.append(cycles['BF_BOOST_INC']) incs.append(cycles['BF_PYTHON_INC']) diff --git a/intern/cycles/blender/CMakeLists.txt b/intern/cycles/blender/CMakeLists.txt index a8c7eef89fa..292c37d6b61 100644 --- a/intern/cycles/blender/CMakeLists.txt +++ b/intern/cycles/blender/CMakeLists.txt @@ -7,6 +7,7 @@ set(INC ../util ../subd ../../guardedalloc + ../../mikktspace ../../../source/blender/makesdna ../../../source/blender/makesrna ../../../source/blender/blenloader @@ -38,6 +39,7 @@ set(ADDON_FILES addon/__init__.py addon/engine.py addon/enums.py + addon/osl.py addon/presets.py addon/properties.py addon/ui.py diff --git a/intern/cycles/blender/addon/__init__.py b/intern/cycles/blender/addon/__init__.py index 6292c09fbb1..16697c08b2b 100644 --- a/intern/cycles/blender/addon/__init__.py +++ b/intern/cycles/blender/addon/__init__.py @@ -71,6 +71,13 @@ class CyclesRender(bpy.types.RenderEngine): def view_draw(self, context): engine.draw(self, context.region, context.space_data, context.region_data) + def update_script_node(self, node): + if engine.with_osl(): + from . import osl + osl.update_script_node(node, self.report) + else: + self.report({'ERROR'}, "OSL support disabled in this build.") + def register(): properties.register() @@ -84,3 +91,4 @@ def unregister(): properties.unregister() presets.unregister() bpy.utils.unregister_module(__name__) + diff --git a/intern/cycles/blender/addon/engine.py b/intern/cycles/blender/addon/engine.py index 05b1f883594..e4f80cb4d5d 100644 --- a/intern/cycles/blender/addon/engine.py +++ b/intern/cycles/blender/addon/engine.py @@ -83,3 +83,4 @@ def available_devices(): def with_osl(): import _cycles return _cycles.with_osl + diff --git a/intern/cycles/blender/addon/enums.py b/intern/cycles/blender/addon/enums.py index 6cc3010eb0e..e63e1e84245 100644 --- a/intern/cycles/blender/addon/enums.py +++ b/intern/cycles/blender/addon/enums.py @@ -60,3 +60,4 @@ panorama_types = ( ('FISHEYE_EQUIDISTANT', "Fisheye Equidistant", "Ideal for fulldomes, ignore the sensor dimensions"), ('FISHEYE_EQUISOLID', "Fisheye Equisolid", "Similar to most fisheye modern lens, take sensor dimensions into consideration"), ) + diff --git a/intern/cycles/blender/addon/osl.py b/intern/cycles/blender/addon/osl.py new file mode 100644 index 00000000000..aac1e2422b9 --- /dev/null +++ b/intern/cycles/blender/addon/osl.py @@ -0,0 +1,127 @@ +# +# Copyright 2011, Blender Foundation. +# +# 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. +# + +# <pep8 compliant> + +import bpy, _cycles, os, tempfile + +# compile .osl file with given filepath to temporary .oso file +def osl_compile(input_path, report): + output_file = tempfile.NamedTemporaryFile(mode='w', suffix=".oso", delete=False) + output_path = output_file.name + output_file.close() + + ok = _cycles.osl_compile(input_path, output_path) + + if ok: + report({'INFO'}, "OSL shader compilation succeeded") + + return ok, output_path + +# compile and update shader script node +def update_script_node(node, report): + import os, shutil + + if node.mode == 'EXTERNAL': + # compile external script file + script_path = bpy.path.abspath(node.filepath, library=node.id_data.library) + script_path_noext, script_ext = os.path.splitext(script_path) + + if script_ext == ".oso": + # it's a .oso file, no need to compile + ok, oso_path = True, script_path + oso_file_remove = False + elif script_ext == ".osl": + # compile .osl file + ok, oso_path = osl_compile(script_path, report) + oso_file_remove = True + + if ok: + # copy .oso from temporary path to .osl directory + dst_path = script_path_noext + ".oso" + try: + shutil.copy2(oso_path, dst_path) + except: + report({'ERROR'}, "Failed to write .oso file next to external .osl file at " + dst_path) + elif os.path.dirname(node.filepath) == "": + # module in search path + oso_path = node.filepath + oso_file_remove = False + ok = True + else: + # unknown + report({'ERROR'}, "External shader script must have .osl or .oso extension, or be a module name") + ok = False + + if ok: + node.bytecode = "" + node.bytecode_hash = "" + + elif node.mode == 'INTERNAL' and node.script: + # internal script, we will store bytecode in the node + script = node.script + osl_path = bpy.path.abspath(script.filepath, library=script.library) + + if script.is_in_memory or script.is_dirty or script.is_modified or not os.path.exists(osl_path): + # write text datablock contents to temporary file + osl_file = tempfile.NamedTemporaryFile(mode='w', suffix=".osl", delete=True) + osl_file.write(script.as_string()) + osl_file.flush() + ok, oso_path = osl_compile(osl_file.name, report) + oso_file_remove = False + osl_file.close() + else: + # compile text datablock from disk directly + ok, oso_path = osl_compile(osl_path, report) + oso_file_remove = False + + if ok: + # read bytecode + try: + oso = open(oso_path, 'r') + node.bytecode = oso.read() + oso.close() + except: + import traceback + traceback.print_exc() + + report({'ERROR'}, "Can't read OSO bytecode to store in node at %r" % oso_path) + ok = False + + else: + report({'WARNING'}, "No text or file specified in node, nothing to compile") + return + + if ok: + # now update node with new sockets + ok = _cycles.osl_update_node(node.id_data.as_pointer(), node.as_pointer(), oso_path) + + if not ok: + report({'ERROR'}, "OSL query failed to open " + oso_path) + else: + report({'ERROR'}, "OSL script compilation failed, see console for errors") + + # remove temporary oso file + if oso_file_remove: + try: + os.remove(oso_path) + except: + pass + + return ok + diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp index 7055cf981c7..b1b1a638219 100644 --- a/intern/cycles/blender/blender_mesh.cpp +++ b/intern/cycles/blender/blender_mesh.cpp @@ -29,32 +29,138 @@ #include "util_foreach.h" +#include "mikktspace.h" + CCL_NAMESPACE_BEGIN -/* Find/Add */ +/* Tangent Space */ -static float3 tangent_from_triangle(float3 v0, float3 v1, float3 v2, float3 tx0, float3 tx1, float3 tx2) -{ - float3 duv1 = tx2 - tx0; - float3 duv2 = tx2 - tx1; - float3 dp1 = v2 - v0; - float3 dp2 = v2 - v1; - float det = duv1[0] * duv2[1] - duv1[1] * duv2[0]; - - if(det != 0.0f) { - return normalize(dp1 * duv2[1] - dp2 * duv1[1]); +struct MikkUserData { + MikkUserData(const BL::Mesh mesh_, const BL::MeshTextureFaceLayer layer_, int num_faces_) + : mesh(mesh_), layer(layer_), num_faces(num_faces_) + { + tangent.resize(num_faces*4); } - else { - /* give back a sane default, using a valid edge as a fallback */ - float3 edge = v1 - v0; - if(len(edge) == 0.0f) - edge = v2 - v0; + BL::Mesh mesh; + BL::MeshTextureFaceLayer layer; + int num_faces; + vector<float4> tangent; +}; + +static int mikk_get_num_faces(const SMikkTSpaceContext *context) +{ + MikkUserData *userdata = (MikkUserData*)context->m_pUserData; + return userdata->num_faces; +} + +static int mikk_get_num_verts_of_face(const SMikkTSpaceContext *context, const int face_num) +{ + MikkUserData *userdata = (MikkUserData*)context->m_pUserData; + BL::MeshTessFace f = userdata->mesh.tessfaces[face_num]; + int4 vi = get_int4(f.vertices_raw()); + + return (vi[3] == 0)? 3: 4; +} - return normalize(edge); +static void mikk_get_position(const SMikkTSpaceContext *context, float P[3], const int face_num, const int vert_num) +{ + MikkUserData *userdata = (MikkUserData*)context->m_pUserData; + BL::MeshTessFace f = userdata->mesh.tessfaces[face_num]; + int4 vi = get_int4(f.vertices_raw()); + BL::MeshVertex v = userdata->mesh.vertices[vi[vert_num]]; + float3 vP = get_float3(v.co()); + + P[0] = vP.x; + P[1] = vP.y; + P[2] = vP.z; +} + +static void mikk_get_texture_coordinate(const SMikkTSpaceContext *context, float uv[2], const int face_num, const int vert_num) +{ + MikkUserData *userdata = (MikkUserData*)context->m_pUserData; + BL::MeshTextureFace tf = userdata->layer.data[face_num]; + float3 tfuv; + + if(vert_num == 0) + tfuv = get_float3(tf.uv1()); + else if(vert_num == 1) + tfuv = get_float3(tf.uv2()); + else if(vert_num == 2) + tfuv = get_float3(tf.uv3()); + else + tfuv = get_float3(tf.uv4()); + + uv[0] = tfuv.x; + uv[1] = tfuv.y; +} + +static void mikk_get_normal(const SMikkTSpaceContext *context, float N[3], const int face_num, const int vert_num) +{ + MikkUserData *userdata = (MikkUserData*)context->m_pUserData; + BL::MeshTessFace f = userdata->mesh.tessfaces[face_num]; + int4 vi = get_int4(f.vertices_raw()); + BL::MeshVertex v = userdata->mesh.vertices[vi[vert_num]]; + float3 vN = get_float3(v.normal()); + + N[0] = vN.x; + N[1] = vN.y; + N[2] = vN.z; +} + +static void mikk_set_tangent_space(const SMikkTSpaceContext *context, const float T[], const float sign, const int face, const int vert) +{ + MikkUserData *userdata = (MikkUserData*)context->m_pUserData; + + userdata->tangent[face*4 + vert] = make_float4(T[0], T[1], T[2], sign); +} + +static void mikk_compute_tangents(BL::Mesh b_mesh, BL::MeshTextureFaceLayer b_layer, Mesh *mesh, vector<int>& nverts) +{ + /* setup userdata */ + MikkUserData userdata(b_mesh, b_layer, nverts.size()); + + /* setup interface */ + SMikkTSpaceInterface interface; + memset(&interface, 0, sizeof(interface)); + interface.m_getNumFaces = mikk_get_num_faces; + interface.m_getNumVerticesOfFace = mikk_get_num_verts_of_face; + interface.m_getPosition = mikk_get_position; + interface.m_getTexCoord = mikk_get_texture_coordinate; + interface.m_getNormal = mikk_get_normal; + interface.m_setTSpaceBasic = mikk_set_tangent_space; + + /* setup context */ + SMikkTSpaceContext context; + memset(&context, 0, sizeof(context)); + context.m_pUserData = &userdata; + context.m_pInterface = &interface; + + /* compute tangents */ + genTangSpaceDefault(&context); + + /* create attribute */ + /* todo: create float4 attribute for sign */ + Attribute *attr = mesh->attributes.add(ATTR_STD_TANGENT, ustring("Tangent")); + float3 *tangent = attr->data_float3(); + + for (int i = 0; i < nverts.size(); i++) { + tangent[0] = float4_to_float3(userdata.tangent[i*4 + 0]); + tangent[1] = float4_to_float3(userdata.tangent[i*4 + 1]); + tangent[2] = float4_to_float3(userdata.tangent[i*4 + 2]); + tangent += 3; + + if(nverts[i] == 4) { + tangent[0] = float4_to_float3(userdata.tangent[i*4 + 0]); + tangent[1] = float4_to_float3(userdata.tangent[i*4 + 2]); + tangent[2] = float4_to_float3(userdata.tangent[i*4 + 3]); + tangent += 3; + } } } +/* Create Mesh */ + static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector<uint>& used_shaders) { /* create vertices */ @@ -167,54 +273,7 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector< if(!l->active_render()) continue; - Attribute *attr = mesh->attributes.add(ATTR_STD_TANGENT, ustring("Tangent")); - - /* compute average tangents per vertex */ - float3 *tangents = attr->data_float3(); - memset(tangents, 0, sizeof(float3)*mesh->verts.size()); - - BL::MeshTextureFaceLayer::data_iterator t; - - size_t fi = 0; /* face index */ - b_mesh.tessfaces.begin(f); - for(l->data.begin(t); t != l->data.end() && f != b_mesh.tessfaces.end(); ++t, ++fi, ++f) { - int4 vi = get_int4(f->vertices_raw()); - - float3 tx0 = get_float3(t->uv1()); - float3 tx1 = get_float3(t->uv2()); - float3 tx2 = get_float3(t->uv3()); - - float3 v0 = mesh->verts[vi[0]]; - float3 v1 = mesh->verts[vi[1]]; - float3 v2 = mesh->verts[vi[2]]; - - /* calculate tangent for the triangle; - * get vertex positions, and find change in position with respect - * to the texture coords in the first texture coord dimension */ - float3 tangent0 = tangent_from_triangle(v0, v1, v2, tx0, tx1, tx2); - - if(nverts[fi] == 4) { - /* quad tangent */ - float3 tx3 = get_float3(t->uv4()); - float3 v3 = mesh->verts[vi[3]]; - float3 tangent1 = tangent_from_triangle(v0, v2, v3, tx0, tx2, tx3); - - tangents[vi[0]] += 0.5f*(tangent0 + tangent1); - tangents[vi[1]] += tangent0; - tangents[vi[2]] += 0.5f*(tangent0 + tangent1); - tangents[vi[3]] += tangent1; - } - else { - /* triangle tangent */ - tangents[vi[0]] += tangent0; - tangents[vi[1]] += tangent0; - tangents[vi[2]] += tangent0; - } - } - - /* normalize tangent vectors */ - for(int i = 0; i < mesh->verts.size(); i++) - tangents[i] = normalize(tangents[i]); + mikk_compute_tangents(b_mesh, *l, mesh, nverts); } } @@ -351,7 +410,7 @@ Mesh *BlenderSync::sync_mesh(BL::Object b_ob, bool object_updated) create_mesh(scene, mesh, b_mesh, used_shaders); /* free derived mesh */ - object_remove_mesh(b_data, b_mesh); + b_data.meshes.remove(b_mesh); } /* displacement method */ @@ -409,7 +468,7 @@ void BlenderSync::sync_mesh_motion(BL::Object b_ob, Mesh *mesh, int motion) mesh->attributes.remove(std); /* free derived mesh */ - object_remove_mesh(b_data, b_mesh); + b_data.meshes.remove(b_mesh); } } diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp index 6de2b0f08fa..1b920249733 100644 --- a/intern/cycles/blender/blender_object.cpp +++ b/intern/cycles/blender/blender_object.cpp @@ -330,10 +330,10 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, int motion) int num_particles = object_count_particles(*b_ob); if(b_ob->is_duplicator()) { - hide = true; /* duplicators hidden by default */ + hide = true; /* duplicators hidden by default */ /* dupli objects */ - object_create_duplilist(*b_ob, b_scene); + b_ob->dupli_list_create(b_scene, 2); BL::Object::dupli_list_iterator b_dup; int b_index = 0; @@ -361,10 +361,9 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, int motion) ++b_index; } - object_free_duplilist(*b_ob); + b_ob->dupli_list_clear(); } - /* sync particles and check if we should render or hide particle emitter */ BL::Object::particle_systems_iterator b_psys; for(b_ob->particle_systems.begin(b_psys); b_psys != b_ob->particle_systems.end(); ++b_psys) { @@ -422,7 +421,7 @@ void BlenderSync::sync_motion(BL::SpaceView3D b_v3d, BL::Object b_override) int frame = b_scene.frame_current(); for(int motion = -1; motion <= 1; motion += 2) { - scene_frame_set(b_scene, frame + motion); + b_scene.frame_set(frame + motion, 0.0f); /* camera object */ if(b_cam) @@ -432,7 +431,7 @@ void BlenderSync::sync_motion(BL::SpaceView3D b_v3d, BL::Object b_override) sync_objects(b_v3d, motion); } - scene_frame_set(b_scene, frame); + b_scene.frame_set(frame, 0.0f); /* tag camera for motion update */ if(scene->camera->motion_modified(prevcam)) diff --git a/intern/cycles/blender/blender_python.cpp b/intern/cycles/blender/blender_python.cpp index d9220b76835..c047805c6ae 100644 --- a/intern/cycles/blender/blender_python.cpp +++ b/intern/cycles/blender/blender_python.cpp @@ -24,9 +24,17 @@ #include "blender_session.h" #include "util_foreach.h" +#include "util_md5.h" #include "util_opengl.h" #include "util_path.h" +#ifdef WITH_OSL +#include "osl.h" + +#include <OSL/oslquery.h> +#include <OSL/oslconfig.h> +#endif + CCL_NAMESPACE_BEGIN static PyObject *init_func(PyObject *self, PyObject *args) @@ -163,6 +171,170 @@ static PyObject *available_devices_func(PyObject *self, PyObject *args) return ret; } +#ifdef WITH_OSL +static PyObject *osl_update_node_func(PyObject *self, PyObject *args) +{ + PyObject *pynodegroup, *pynode; + const char *filepath = NULL; + + if(!PyArg_ParseTuple(args, "OOs", &pynodegroup, &pynode, &filepath)) + return NULL; + + /* RNA */ + PointerRNA nodeptr; + RNA_pointer_create((ID*)PyLong_AsVoidPtr(pynodegroup), &RNA_ShaderNodeScript, (void*)PyLong_AsVoidPtr(pynode), &nodeptr); + BL::ShaderNodeScript b_node(nodeptr); + + /* update bytecode hash */ + string bytecode = b_node.bytecode(); + + if(!bytecode.empty()) { + MD5Hash md5; + md5.append((const uint8_t*)bytecode.c_str(), bytecode.size()); + b_node.bytecode_hash(md5.get_hex().c_str()); + } + else + b_node.bytecode_hash(""); + + /* query from file path */ + OSL::OSLQuery query; + + if(!OSLShaderManager::osl_query(query, filepath)) + Py_RETURN_FALSE; + + /* add new sockets from parameters */ + set<void*> used_sockets; + + for(int i = 0; i < query.nparams(); i++) { + const OSL::OSLQuery::Parameter *param = query.getparam(i); + + /* skip unsupported types */ + if(param->varlenarray || param->isstruct || param->type.arraylen > 1) + continue; + + /* determine socket type */ + BL::NodeSocket::type_enum socket_type; + float default_float4[4] = {0.0f, 0.0f, 0.0f, 1.0f}; + float default_float = 0.0f; + int default_int = 0; + + if(param->isclosure) { + socket_type = BL::NodeSocket::type_SHADER; + } + else if(param->type.vecsemantics == TypeDesc::COLOR) { + socket_type = BL::NodeSocket::type_RGBA; + + if(param->validdefault) { + default_float4[0] = param->fdefault[0]; + default_float4[1] = param->fdefault[1]; + default_float4[2] = param->fdefault[2]; + } + } + else if(param->type.vecsemantics == TypeDesc::POINT || + param->type.vecsemantics == TypeDesc::VECTOR || + param->type.vecsemantics == TypeDesc::NORMAL) { + socket_type = BL::NodeSocket::type_VECTOR; + + if(param->validdefault) { + default_float4[0] = param->fdefault[0]; + default_float4[1] = param->fdefault[1]; + default_float4[2] = param->fdefault[2]; + } + } + else if(param->type.aggregate == TypeDesc::SCALAR) { + if(param->type.basetype == TypeDesc::INT) { + socket_type = BL::NodeSocket::type_INT; + if(param->validdefault) + default_int = param->idefault[0]; + } + else if(param->type.basetype == TypeDesc::FLOAT) { + socket_type = BL::NodeSocket::type_VALUE; + if(param->validdefault) + default_float = param->fdefault[0]; + } + } + else + continue; + + /* find socket socket */ + BL::NodeSocket b_sock = b_node.find_socket(param->name.c_str(), param->isoutput); + + /* remove if type no longer matches */ + if(b_sock && b_sock.type() != socket_type) { + b_node.remove_socket(b_sock); + b_sock = BL::NodeSocket(PointerRNA_NULL); + } + + /* create new socket */ + if(!b_sock) { + b_sock = b_node.add_socket(param->name.c_str(), socket_type, param->isoutput); + + /* set default value */ + if(socket_type == BL::NodeSocket::type_VALUE) { + BL::NodeSocketFloatNone b_float_sock(b_sock.ptr); + b_float_sock.default_value(default_float); + } + else if(socket_type == BL::NodeSocket::type_INT) { + BL::NodeSocketIntNone b_int_sock(b_sock.ptr); + b_int_sock.default_value(default_int); + } + else if(socket_type == BL::NodeSocket::type_RGBA) { + BL::NodeSocketRGBA b_rgba_sock(b_sock.ptr); + b_rgba_sock.default_value(default_float4); + } + else if(socket_type == BL::NodeSocket::type_VECTOR) { + BL::NodeSocketVectorNone b_vector_sock(b_sock.ptr); + b_vector_sock.default_value(default_float4); + } + } + + used_sockets.insert(b_sock.ptr.data); + } + + /* remove unused parameters */ + bool removed; + + do { + BL::Node::inputs_iterator b_input; + BL::Node::outputs_iterator b_output; + + removed = false; + + for (b_node.inputs.begin(b_input); b_input != b_node.inputs.end(); ++b_input) { + if(used_sockets.find(b_input->ptr.data) == used_sockets.end()) { + b_node.remove_socket(*b_input); + removed = true; + break; + } + } + + for (b_node.outputs.begin(b_output); b_output != b_node.outputs.end(); ++b_output) { + if(used_sockets.find(b_output->ptr.data) == used_sockets.end()) { + b_node.remove_socket(*b_output); + removed = true; + break; + } + } + } while(removed); + + Py_RETURN_TRUE; +} + +static PyObject *osl_compile_func(PyObject *self, PyObject *args) +{ + const char *inputfile = NULL, *outputfile = NULL; + + if(!PyArg_ParseTuple(args, "ss", &inputfile, &outputfile)) + return NULL; + + /* return */ + if(!OSLShaderManager::osl_compile(inputfile, outputfile)) + Py_RETURN_FALSE; + + Py_RETURN_TRUE; +} +#endif + static PyMethodDef methods[] = { {"init", init_func, METH_VARARGS, ""}, {"create", create_func, METH_VARARGS, ""}, @@ -170,6 +342,10 @@ static PyMethodDef methods[] = { {"render", render_func, METH_O, ""}, {"draw", draw_func, METH_VARARGS, ""}, {"sync", sync_func, METH_O, ""}, +#ifdef WITH_OSL + {"osl_update_node", osl_update_node_func, METH_VARARGS, ""}, + {"osl_compile", osl_compile_func, METH_VARARGS, ""}, +#endif {"available_devices", available_devices_func, METH_NOARGS, ""}, {NULL, NULL, 0, NULL}, }; diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp index 0ce1a7dcf28..9e3380c6f8e 100644 --- a/intern/cycles/blender/blender_shader.cpp +++ b/intern/cycles/blender/blender_shader.cpp @@ -20,6 +20,7 @@ #include "graph.h" #include "light.h" #include "nodes.h" +#include "osl.h" #include "scene.h" #include "shader.h" @@ -43,6 +44,7 @@ void BlenderSync::find_shader(BL::ID id, vector<uint>& used_shaders, int default for(size_t i = 0; i < scene->shaders.size(); i++) { if(scene->shaders[i] == shader) { used_shaders.push_back(i); + scene->shaders[i]->tag_used(scene); break; } } @@ -158,7 +160,7 @@ static void get_tex_mapping(TextureMapping *mapping, BL::ShaderNodeMapping b_map mapping->max = get_float3(b_mapping.max()); } -static ShaderNode *add_node(BL::BlendData b_data, BL::Scene b_scene, ShaderGraph *graph, BL::ShaderNode b_node) +static ShaderNode *add_node(Scene *scene, BL::BlendData b_data, BL::Scene b_scene, ShaderGraph *graph, BL::ShaderNodeTree b_ntree, BL::ShaderNode b_node) { ShaderNode *node = NULL; @@ -412,6 +414,58 @@ static ShaderNode *add_node(BL::BlendData b_data, BL::Scene b_scene, ShaderGraph node = new BumpNode(); break; } + case BL::ShaderNode::type_SCRIPT: { +#ifdef WITH_OSL + if(scene->params.shadingsystem != SceneParams::OSL) + break; + + /* create script node */ + BL::ShaderNodeScript b_script_node(b_node); + OSLScriptNode *script_node = new OSLScriptNode(); + + /* Generate inputs/outputs from node sockets + * + * Note: the node sockets are generated from OSL parameters, + * so the names match those of the corresponding parameters exactly. + * + * Note 2: ShaderInput/ShaderOutput store shallow string copies only! + * Socket names must be stored in the extra lists instead. */ + BL::Node::inputs_iterator b_input; + + for (b_script_node.inputs.begin(b_input); b_input != b_script_node.inputs.end(); ++b_input) { + script_node->input_names.push_back(ustring(b_input->name())); + ShaderInput *input = script_node->add_input(script_node->input_names.back().c_str(), convert_socket_type(b_input->type())); + set_default_value(input, *b_input); + } + + BL::Node::outputs_iterator b_output; + + for (b_script_node.outputs.begin(b_output); b_output != b_script_node.outputs.end(); ++b_output) { + script_node->output_names.push_back(ustring(b_output->name())); + script_node->add_output(script_node->output_names.back().c_str(), convert_socket_type(b_output->type())); + } + + /* load bytecode or filepath */ + OSLShaderManager *manager = (OSLShaderManager*)scene->shader_manager; + string bytecode_hash = b_script_node.bytecode_hash(); + + if(!bytecode_hash.empty()) { + /* loaded bytecode if not already done */ + if(!manager->shader_test_loaded(bytecode_hash)) + manager->shader_load_bytecode(bytecode_hash, b_script_node.bytecode()); + + script_node->bytecode_hash = bytecode_hash; + } + else { + /* set filepath */ + script_node->filepath = blender_absolute_path(b_data, b_ntree, b_script_node.filepath()); + } + + node = script_node; +#endif + + break; + } case BL::ShaderNode::type_TEX_IMAGE: { BL::ShaderNodeTexImage b_image_node(b_node); BL::Image b_image(b_image_node.image()); @@ -575,7 +629,7 @@ static SocketPair node_socket_map_pair(PtrNodeMap& node_map, BL::Node b_node, BL return SocketPair(node_map[b_node.ptr.data], name); } -static void add_nodes(BL::BlendData b_data, BL::Scene b_scene, ShaderGraph *graph, BL::ShaderNodeTree b_ntree, PtrSockMap& sockets_map) +static void add_nodes(Scene *scene, BL::BlendData b_data, BL::Scene b_scene, ShaderGraph *graph, BL::ShaderNodeTree b_ntree, PtrSockMap& sockets_map) { /* add nodes */ BL::ShaderNodeTree::nodes_iterator b_node; @@ -650,10 +704,10 @@ static void add_nodes(BL::BlendData b_data, BL::Scene b_scene, ShaderGraph *grap set_default_value(proxy->inputs[0], b_output->group_socket()); } - add_nodes(b_data, b_scene, graph, b_group_ntree, group_sockmap); + add_nodes(scene, b_data, b_scene, graph, b_group_ntree, group_sockmap); } else { - ShaderNode *node = add_node(b_data, b_scene, graph, BL::ShaderNode(*b_node)); + ShaderNode *node = add_node(scene, b_data, b_scene, graph, b_ntree, BL::ShaderNode(*b_node)); if(node) { BL::Node::inputs_iterator b_input; @@ -743,7 +797,7 @@ void BlenderSync::sync_materials() PtrSockMap sock_to_node; BL::ShaderNodeTree b_ntree(b_mat->node_tree()); - add_nodes(b_data, b_scene, graph, b_ntree, sock_to_node); + add_nodes(scene, b_data, b_scene, graph, b_ntree, sock_to_node); } else { ShaderNode *closure, *out; @@ -784,7 +838,7 @@ void BlenderSync::sync_world() PtrSockMap sock_to_node; BL::ShaderNodeTree b_ntree(b_world.node_tree()); - add_nodes(b_data, b_scene, graph, b_ntree, sock_to_node); + add_nodes(scene, b_data, b_scene, graph, b_ntree, sock_to_node); } else if(b_world) { ShaderNode *closure, *out; @@ -843,7 +897,7 @@ void BlenderSync::sync_lamps() PtrSockMap sock_to_node; BL::ShaderNodeTree b_ntree(b_lamp->node_tree()); - add_nodes(b_data, b_scene, graph, b_ntree, sock_to_node); + add_nodes(scene, b_data, b_scene, graph, b_ntree, sock_to_node); } else { ShaderNode *closure, *out; diff --git a/intern/cycles/blender/blender_util.h b/intern/cycles/blender/blender_util.h index 079320e909c..df1e99882b8 100644 --- a/intern/cycles/blender/blender_util.h +++ b/intern/cycles/blender/blender_util.h @@ -39,7 +39,7 @@ CCL_NAMESPACE_BEGIN static inline BL::Mesh object_to_mesh(BL::Object self, BL::Scene scene, bool apply_modifiers, bool render) { - return self.to_mesh(NULL, scene, apply_modifiers, (render)? 2: 1); + return self.to_mesh(scene, apply_modifiers, (render)? 2: 1); } static inline void colorramp_to_array(BL::ColorRamp ramp, float4 *data, int size) @@ -52,24 +52,6 @@ static inline void colorramp_to_array(BL::ColorRamp ramp, float4 *data, int size } } -static inline void object_remove_mesh(BL::BlendData data, BL::Mesh mesh) -{ - /* TODO: BlendData.meshes ideally should be also a subclass of BlendDataMeshes */ - BL::BlendDataMeshes mesh_data(data.ptr); - - mesh_data.remove(NULL, mesh); -} - -static inline void object_create_duplilist(BL::Object self, BL::Scene scene) -{ - self.dupli_list_create(NULL, scene, 2); -} - -static inline void object_free_duplilist(BL::Object self) -{ - self.dupli_list_clear(); -} - static inline bool BKE_object_is_modified(BL::Object self, BL::Scene scene, bool preview) { return self.is_modified(scene, (preview)? (1<<0): (1<<1))? true: false; @@ -88,11 +70,6 @@ static inline string image_user_file_path(BL::ImageUser iuser, BL::Image ima, in return string(filepath); } -static inline void scene_frame_set(BL::Scene scene, int frame) -{ - scene.frame_set(frame, 0.0f); -} - /* Utilities */ static inline Transform get_transform(BL::Array<float, 16> array) diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt index d24c7d4128c..82b0605ab6b 100644 --- a/intern/cycles/kernel/CMakeLists.txt +++ b/intern/cycles/kernel/CMakeLists.txt @@ -134,6 +134,7 @@ endif() if(WITH_CYCLES_OSL) add_subdirectory(osl) + add_subdirectory(shaders) endif() # CPU module diff --git a/intern/cycles/kernel/closure/bsdf_microfacet.h b/intern/cycles/kernel/closure/bsdf_microfacet.h index f671e858481..a564b99e759 100644 --- a/intern/cycles/kernel/closure/bsdf_microfacet.h +++ b/intern/cycles/kernel/closure/bsdf_microfacet.h @@ -45,13 +45,10 @@ __device_inline float safe_sqrtf(float f) __device int bsdf_microfacet_ggx_setup(ShaderClosure *sc) { float ag = sc->data0; - float eta = sc->data1; float m_ag = clamp(ag, 1e-4f, 1.0f); - float m_eta = eta; sc->data0 = m_ag; - sc->data1 = m_eta; sc->type = CLOSURE_BSDF_MICROFACET_GGX_ID; return SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY; @@ -82,7 +79,6 @@ __device void bsdf_microfacet_ggx_blur(ShaderClosure *sc, float roughness) __device float3 bsdf_microfacet_ggx_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { float m_ag = sc->data0; - //float m_eta = sc->data1; int m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID; float3 N = sc->N; @@ -155,7 +151,6 @@ __device float3 bsdf_microfacet_ggx_eval_transmit(const ShaderClosure *sc, const __device int bsdf_microfacet_ggx_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) { float m_ag = sc->data0; - float m_eta = sc->data1; int m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID; float3 N = sc->N; @@ -221,6 +216,7 @@ __device int bsdf_microfacet_ggx_sample(const ShaderClosure *sc, float3 Ng, floa #ifdef __RAY_DIFFERENTIALS__ float3 dRdx, dRdy, dTdx, dTdy; #endif + float m_eta = sc->data1; bool inside; fresnel_dielectric(m_eta, m, I, &R, &T, #ifdef __RAY_DIFFERENTIALS__ @@ -274,12 +270,9 @@ __device int bsdf_microfacet_ggx_sample(const ShaderClosure *sc, float3 Ng, floa __device int bsdf_microfacet_beckmann_setup(ShaderClosure *sc) { float ab = sc->data0; - float eta = sc->data1; float m_ab = clamp(ab, 1e-4f, 1.0f); - float m_eta = eta; sc->data0 = m_ab; - sc->data1 = m_eta; sc->type = CLOSURE_BSDF_MICROFACET_BECKMANN_ID; return SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY; @@ -309,7 +302,6 @@ __device void bsdf_microfacet_beckmann_blur(ShaderClosure *sc, float roughness) __device float3 bsdf_microfacet_beckmann_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf) { float m_ab = sc->data0; - //float m_eta = sc->data1; int m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID; float3 N = sc->N; @@ -386,7 +378,6 @@ __device float3 bsdf_microfacet_beckmann_eval_transmit(const ShaderClosure *sc, __device int bsdf_microfacet_beckmann_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf) { float m_ab = sc->data0; - float m_eta = sc->data1; int m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID; float3 N = sc->N; @@ -456,6 +447,7 @@ __device int bsdf_microfacet_beckmann_sample(const ShaderClosure *sc, float3 Ng, #ifdef __RAY_DIFFERENTIALS__ float3 dRdx, dRdy, dTdx, dTdy; #endif + float m_eta = sc->data1; bool inside; fresnel_dielectric(m_eta, m, I, &R, &T, #ifdef __RAY_DIFFERENTIALS__ diff --git a/intern/cycles/kernel/kernel_triangle.h b/intern/cycles/kernel/kernel_triangle.h index 43cfa330724..e39ae1d4fbc 100644 --- a/intern/cycles/kernel/kernel_triangle.h +++ b/intern/cycles/kernel/kernel_triangle.h @@ -68,6 +68,17 @@ __device_inline float3 triangle_normal_MT(KernelGlobals *kg, int tri_index, int #endif } +/* Return 3 triangle vertex locations */ +__device_inline void triangle_vertices(KernelGlobals *kg, int tri_index, float3 P[3]) +{ + /* load triangle vertices */ + float3 tri_vindex = float4_to_float3(kernel_tex_fetch(__tri_vindex, tri_index)); + + P[0] = float4_to_float3(kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.x))); + P[1] = float4_to_float3(kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.y))); + P[2] = float4_to_float3(kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.z))); +} + __device_inline float3 triangle_smooth_normal(KernelGlobals *kg, int tri_index, float u, float v) { /* load triangle vertices */ diff --git a/intern/cycles/kernel/osl/CMakeLists.txt b/intern/cycles/kernel/osl/CMakeLists.txt index d6449b4349b..8938b16a48f 100644 --- a/intern/cycles/kernel/osl/CMakeLists.txt +++ b/intern/cycles/kernel/osl/CMakeLists.txt @@ -34,4 +34,3 @@ include_directories(SYSTEM ${INC_SYS}) add_library(cycles_kernel_osl ${SRC} ${HEADER_SRC}) -add_subdirectory(nodes) diff --git a/intern/cycles/kernel/osl/osl_services.cpp b/intern/cycles/kernel/osl/osl_services.cpp index 7c415e22012..ade085c795d 100644 --- a/intern/cycles/kernel/osl/osl_services.cpp +++ b/intern/cycles/kernel/osl/osl_services.cpp @@ -345,6 +345,51 @@ static void set_attribute_float(float f[3], TypeDesc type, bool derivatives, voi } } +static bool set_attribute_int(int i, TypeDesc type, bool derivatives, void *val) +{ + if(type.basetype == TypeDesc::INT && type.aggregate == TypeDesc::SCALAR && type.arraylen == 0) { + int *ival = (int *)val; + ival[0] = i; + + if (derivatives) { + ival[1] = 0; + ival[2] = 0; + } + + return true; + } + + return false; +} + +static bool set_attribute_float3_3(float3 P[3], TypeDesc type, bool derivatives, void *val) +{ + if(type.vecsemantics == TypeDesc::POINT && type.arraylen >= 3) { + float *fval = (float *)val; + + fval[0] = P[0].x; + fval[1] = P[0].y; + fval[2] = P[0].z; + + fval[3] = P[1].x; + fval[4] = P[1].y; + fval[5] = P[1].z; + + fval[6] = P[2].x; + fval[7] = P[2].y; + fval[8] = P[2].z; + + if(type.arraylen > 3) + memset(fval + 3*3, 0, sizeof(float)*3*(type.arraylen - 3)); + if (derivatives) + memset(fval + type.arraylen*3, 0, sizeof(float)*2*3*type.arraylen); + + return true; + } + + return false; +} + static bool get_mesh_attribute(KernelGlobals *kg, const ShaderData *sd, const OSLGlobals::Attribute& attr, const TypeDesc& type, bool derivatives, void *val) { @@ -381,43 +426,45 @@ static void get_object_attribute(const OSLGlobals::Attribute& attr, bool derivat static bool get_object_standard_attribute(KernelGlobals *kg, ShaderData *sd, ustring name, TypeDesc type, bool derivatives, void *val) { + /* todo: turn this into hash table + callback once */ + /* Object Attributes */ - if (name == "std::object_location") { + if (name == "object:location") { float3 fval[3]; fval[0] = object_location(kg, sd); fval[1] = fval[2] = make_float3(0.0, 0.0, 0.0); /* derivates set to 0 */ set_attribute_float3(fval, type, derivatives, val); return true; } - else if (name == "std::object_index") { + else if (name == "object:index") { float fval[3]; fval[0] = object_pass_id(kg, sd->object); fval[1] = fval[2] = 0.0; /* derivates set to 0 */ set_attribute_float(fval, type, derivatives, val); return true; } - else if (name == "std::dupli_generated") { + else if (name == "geom:dupli_generated") { float3 fval[3]; fval[0] = object_dupli_generated(kg, sd->object); fval[1] = fval[2] = make_float3(0.0, 0.0, 0.0); /* derivates set to 0 */ set_attribute_float3(fval, type, derivatives, val); return true; } - else if (name == "std::dupli_uv") { + else if (name == "geom:dupli_uv") { float3 fval[3]; fval[0] = object_dupli_uv(kg, sd->object); fval[1] = fval[2] = make_float3(0.0, 0.0, 0.0); /* derivates set to 0 */ set_attribute_float3(fval, type, derivatives, val); return true; } - else if (name == "std::material_index") { + else if (name == "material:index") { float fval[3]; fval[0] = shader_pass_id(kg, sd); fval[1] = fval[2] = 0.0; /* derivates set to 0 */ set_attribute_float(fval, type, derivatives, val); return true; } - else if (name == "std::object_random") { + else if (name == "object:random") { float fval[3]; fval[0] = object_random_number(kg, sd->object); fval[1] = fval[2] = 0.0; /* derivates set to 0 */ @@ -426,7 +473,7 @@ static bool get_object_standard_attribute(KernelGlobals *kg, ShaderData *sd, ust } /* Particle Attributes */ - else if (name == "std::particle_index") { + else if (name == "particle:index") { float fval[3]; uint particle_id = object_particle_id(kg, sd->object); fval[0] = particle_index(kg, particle_id); @@ -434,7 +481,7 @@ static bool get_object_standard_attribute(KernelGlobals *kg, ShaderData *sd, ust set_attribute_float(fval, type, derivatives, val); return true; } - else if (name == "std::particle_age") { + else if (name == "particle:age") { float fval[3]; uint particle_id = object_particle_id(kg, sd->object); fval[0] = particle_age(kg, particle_id); @@ -442,7 +489,7 @@ static bool get_object_standard_attribute(KernelGlobals *kg, ShaderData *sd, ust set_attribute_float(fval, type, derivatives, val); return true; } - else if (name == "std::particle_lifetime") { + else if (name == "particle:lifetime") { float fval[3]; uint particle_id = object_particle_id(kg, sd->object); fval[0] = particle_lifetime(kg, particle_id); @@ -450,7 +497,7 @@ static bool get_object_standard_attribute(KernelGlobals *kg, ShaderData *sd, ust set_attribute_float(fval, type, derivatives, val); return true; } - else if (name == "std::particle_location") { + else if (name == "particle:location") { float3 fval[3]; uint particle_id = object_particle_id(kg, sd->object); fval[0] = particle_location(kg, particle_id); @@ -459,7 +506,7 @@ static bool get_object_standard_attribute(KernelGlobals *kg, ShaderData *sd, ust return true; } #if 0 /* unsupported */ - else if (name == "std::particle_rotation") { + else if (name == "particle:rotation") { float4 fval[3]; uint particle_id = object_particle_id(kg, sd->object); fval[0] = particle_rotation(kg, particle_id); @@ -468,7 +515,7 @@ static bool get_object_standard_attribute(KernelGlobals *kg, ShaderData *sd, ust return true; } #endif - else if (name == "std::particle_size") { + else if (name == "particle:size") { float fval[3]; uint particle_id = object_particle_id(kg, sd->object); fval[0] = particle_size(kg, particle_id); @@ -476,7 +523,7 @@ static bool get_object_standard_attribute(KernelGlobals *kg, ShaderData *sd, ust set_attribute_float(fval, type, derivatives, val); return true; } - else if (name == "std::particle_velocity") { + else if (name == "particle:velocity") { float3 fval[3]; uint particle_id = object_particle_id(kg, sd->object); fval[0] = particle_velocity(kg, particle_id); @@ -484,7 +531,7 @@ static bool get_object_standard_attribute(KernelGlobals *kg, ShaderData *sd, ust set_attribute_float3(fval, type, derivatives, val); return true; } - else if (name == "std::particle_angular_velocity") { + else if (name == "particle:angular_velocity") { float3 fval[3]; uint particle_id = object_particle_id(kg, sd->object); fval[0] = particle_angular_velocity(kg, particle_id); @@ -492,7 +539,17 @@ static bool get_object_standard_attribute(KernelGlobals *kg, ShaderData *sd, ust set_attribute_float3(fval, type, derivatives, val); return true; } - + else if (name == "geom:numpolyvertices") { + return set_attribute_int(3, type, derivatives, val); + } + else if (name == "geom:trianglevertices" || name == "geom:polyvertices") { + float3 P[3]; + triangle_vertices(kg, sd->prim, P); + object_position_transform(kg, sd, &P[0]); + object_position_transform(kg, sd, &P[1]); + object_position_transform(kg, sd, &P[2]); + return set_attribute_float3_3(P, type, derivatives, val); + } else return false; } @@ -501,7 +558,7 @@ static bool get_background_attribute(KernelGlobals *kg, ShaderData *sd, ustring TypeDesc type, bool derivatives, void *val) { /* Ray Length */ - if (name == "std::ray_length") { + if (name == "path:ray_length") { float fval[3]; fval[0] = sd->ray_length; fval[1] = fval[2] = 0.0; /* derivates set to 0 */ diff --git a/intern/cycles/kernel/osl/nodes/CMakeLists.txt b/intern/cycles/kernel/shaders/CMakeLists.txt index da5441f11e0..00ab52a1d13 100644 --- a/intern/cycles/kernel/osl/nodes/CMakeLists.txt +++ b/intern/cycles/kernel/shaders/CMakeLists.txt @@ -76,11 +76,11 @@ set(SRC_OSO # TODO, add a module to compile OSL foreach(_file ${SRC_OSL}) set(_OSL_FILE ${CMAKE_CURRENT_SOURCE_DIR}/${_file}) - string(REPLACE ".osl" ".oso" _OSO_FILE ${_OSL_FILE}) # TODO, replace extension only + string(REPLACE ".osl" ".oso" _OSO_FILE ${_OSL_FILE}) string(REPLACE ${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR} _OSO_FILE ${_OSO_FILE}) add_custom_command( OUTPUT ${_OSO_FILE} - COMMAND ${OSL_COMPILER} -O2 ${_OSL_FILE} + COMMAND ${OSL_COMPILER} -O2 -I"${CMAKE_CURRENT_SOURCE_DIR}" ${_OSL_FILE} DEPENDS ${_OSL_FILE} ${SRC_OSL_HEADERS}) list(APPEND SRC_OSO ${_OSO_FILE} @@ -94,3 +94,5 @@ add_custom_target(cycles_osl_shaders ALL DEPENDS ${SRC_OSO} ${SRC_OSL_HEADERS}) # CMAKE_CURRENT_SOURCE_DIR is already included in OSO paths delayed_install("" "${SRC_OSO}" ${CYCLES_INSTALL_PATH}/shader) +delayed_install("${CMAKE_CURRENT_SOURCE_DIR}" "${SRC_OSL_HEADERS}" ${CYCLES_INSTALL_PATH}/shader) + diff --git a/intern/cycles/kernel/osl/nodes/node_add_closure.osl b/intern/cycles/kernel/shaders/node_add_closure.osl index ecf6bf5912e..ecf6bf5912e 100644 --- a/intern/cycles/kernel/osl/nodes/node_add_closure.osl +++ b/intern/cycles/kernel/shaders/node_add_closure.osl diff --git a/intern/cycles/kernel/osl/nodes/node_attribute.osl b/intern/cycles/kernel/shaders/node_attribute.osl index 8e7c846d1a3..8e7c846d1a3 100644 --- a/intern/cycles/kernel/osl/nodes/node_attribute.osl +++ b/intern/cycles/kernel/shaders/node_attribute.osl diff --git a/intern/cycles/kernel/osl/nodes/node_background.osl b/intern/cycles/kernel/shaders/node_background.osl index b51a1685294..b51a1685294 100644 --- a/intern/cycles/kernel/osl/nodes/node_background.osl +++ b/intern/cycles/kernel/shaders/node_background.osl diff --git a/intern/cycles/kernel/osl/nodes/node_brick_texture.osl b/intern/cycles/kernel/shaders/node_brick_texture.osl index 478d9457001..478d9457001 100644 --- a/intern/cycles/kernel/osl/nodes/node_brick_texture.osl +++ b/intern/cycles/kernel/shaders/node_brick_texture.osl diff --git a/intern/cycles/kernel/osl/nodes/node_brightness.osl b/intern/cycles/kernel/shaders/node_brightness.osl index 8e9f5c9c796..8e9f5c9c796 100644 --- a/intern/cycles/kernel/osl/nodes/node_brightness.osl +++ b/intern/cycles/kernel/shaders/node_brightness.osl diff --git a/intern/cycles/kernel/osl/nodes/node_bump.osl b/intern/cycles/kernel/shaders/node_bump.osl index 24db1b24458..24db1b24458 100644 --- a/intern/cycles/kernel/osl/nodes/node_bump.osl +++ b/intern/cycles/kernel/shaders/node_bump.osl diff --git a/intern/cycles/kernel/osl/nodes/node_camera.osl b/intern/cycles/kernel/shaders/node_camera.osl index 898ebd2bbb2..898ebd2bbb2 100644 --- a/intern/cycles/kernel/osl/nodes/node_camera.osl +++ b/intern/cycles/kernel/shaders/node_camera.osl diff --git a/intern/cycles/kernel/osl/nodes/node_checker_texture.osl b/intern/cycles/kernel/shaders/node_checker_texture.osl index 577caf308ff..577caf308ff 100644 --- a/intern/cycles/kernel/osl/nodes/node_checker_texture.osl +++ b/intern/cycles/kernel/shaders/node_checker_texture.osl diff --git a/intern/cycles/kernel/osl/nodes/node_color.h b/intern/cycles/kernel/shaders/node_color.h index 80786e4e369..80786e4e369 100644 --- a/intern/cycles/kernel/osl/nodes/node_color.h +++ b/intern/cycles/kernel/shaders/node_color.h diff --git a/intern/cycles/kernel/osl/nodes/node_combine_rgb.osl b/intern/cycles/kernel/shaders/node_combine_rgb.osl index 546369f660e..546369f660e 100644 --- a/intern/cycles/kernel/osl/nodes/node_combine_rgb.osl +++ b/intern/cycles/kernel/shaders/node_combine_rgb.osl diff --git a/intern/cycles/kernel/osl/nodes/node_convert_from_color.osl b/intern/cycles/kernel/shaders/node_convert_from_color.osl index 2884c772414..2884c772414 100644 --- a/intern/cycles/kernel/osl/nodes/node_convert_from_color.osl +++ b/intern/cycles/kernel/shaders/node_convert_from_color.osl diff --git a/intern/cycles/kernel/osl/nodes/node_convert_from_float.osl b/intern/cycles/kernel/shaders/node_convert_from_float.osl index 4466fbae3a6..4466fbae3a6 100644 --- a/intern/cycles/kernel/osl/nodes/node_convert_from_float.osl +++ b/intern/cycles/kernel/shaders/node_convert_from_float.osl diff --git a/intern/cycles/kernel/osl/nodes/node_convert_from_int.osl b/intern/cycles/kernel/shaders/node_convert_from_int.osl index 060d4184fa6..060d4184fa6 100644 --- a/intern/cycles/kernel/osl/nodes/node_convert_from_int.osl +++ b/intern/cycles/kernel/shaders/node_convert_from_int.osl diff --git a/intern/cycles/kernel/osl/nodes/node_convert_from_normal.osl b/intern/cycles/kernel/shaders/node_convert_from_normal.osl index 32ef430d93b..32ef430d93b 100644 --- a/intern/cycles/kernel/osl/nodes/node_convert_from_normal.osl +++ b/intern/cycles/kernel/shaders/node_convert_from_normal.osl diff --git a/intern/cycles/kernel/osl/nodes/node_convert_from_point.osl b/intern/cycles/kernel/shaders/node_convert_from_point.osl index a9435c8abf4..a9435c8abf4 100644 --- a/intern/cycles/kernel/osl/nodes/node_convert_from_point.osl +++ b/intern/cycles/kernel/shaders/node_convert_from_point.osl diff --git a/intern/cycles/kernel/osl/nodes/node_convert_from_vector.osl b/intern/cycles/kernel/shaders/node_convert_from_vector.osl index 4516f92c753..4516f92c753 100644 --- a/intern/cycles/kernel/osl/nodes/node_convert_from_vector.osl +++ b/intern/cycles/kernel/shaders/node_convert_from_vector.osl diff --git a/intern/cycles/kernel/osl/nodes/node_diffuse_bsdf.osl b/intern/cycles/kernel/shaders/node_diffuse_bsdf.osl index d6dc17316e8..d6dc17316e8 100644 --- a/intern/cycles/kernel/osl/nodes/node_diffuse_bsdf.osl +++ b/intern/cycles/kernel/shaders/node_diffuse_bsdf.osl diff --git a/intern/cycles/kernel/osl/nodes/node_emission.osl b/intern/cycles/kernel/shaders/node_emission.osl index 7ad0f9f7760..7ad0f9f7760 100644 --- a/intern/cycles/kernel/osl/nodes/node_emission.osl +++ b/intern/cycles/kernel/shaders/node_emission.osl diff --git a/intern/cycles/kernel/osl/nodes/node_environment_texture.osl b/intern/cycles/kernel/shaders/node_environment_texture.osl index bad62e56ab4..bad62e56ab4 100644 --- a/intern/cycles/kernel/osl/nodes/node_environment_texture.osl +++ b/intern/cycles/kernel/shaders/node_environment_texture.osl diff --git a/intern/cycles/kernel/osl/nodes/node_fresnel.h b/intern/cycles/kernel/shaders/node_fresnel.h index dfd0a23fe1e..dfd0a23fe1e 100644 --- a/intern/cycles/kernel/osl/nodes/node_fresnel.h +++ b/intern/cycles/kernel/shaders/node_fresnel.h diff --git a/intern/cycles/kernel/osl/nodes/node_fresnel.osl b/intern/cycles/kernel/shaders/node_fresnel.osl index e8d8e945f98..e8d8e945f98 100644 --- a/intern/cycles/kernel/osl/nodes/node_fresnel.osl +++ b/intern/cycles/kernel/shaders/node_fresnel.osl diff --git a/intern/cycles/kernel/osl/nodes/node_gamma.osl b/intern/cycles/kernel/shaders/node_gamma.osl index d55e908b0b7..d55e908b0b7 100644 --- a/intern/cycles/kernel/osl/nodes/node_gamma.osl +++ b/intern/cycles/kernel/shaders/node_gamma.osl diff --git a/intern/cycles/kernel/osl/nodes/node_geometry.osl b/intern/cycles/kernel/shaders/node_geometry.osl index a3831cbec9c..a3831cbec9c 100644 --- a/intern/cycles/kernel/osl/nodes/node_geometry.osl +++ b/intern/cycles/kernel/shaders/node_geometry.osl diff --git a/intern/cycles/kernel/osl/nodes/node_glass_bsdf.osl b/intern/cycles/kernel/shaders/node_glass_bsdf.osl index f3fcce572cf..30b9d301f32 100644 --- a/intern/cycles/kernel/osl/nodes/node_glass_bsdf.osl +++ b/intern/cycles/kernel/shaders/node_glass_bsdf.osl @@ -34,10 +34,10 @@ shader node_glass_bsdf( if (distribution == "Sharp") BSDF = Color * (Fr * reflection(Normal) + (1.0 - Fr) * refraction(Normal, eta)); else if (distribution == "Beckmann") - BSDF = Color * (Fr * microfacet_beckmann(Normal, Roughness, eta) + + BSDF = Color * (Fr * microfacet_beckmann(Normal, Roughness) + (1.0 - Fr) * microfacet_beckmann_refraction(Normal, Roughness, eta)); else if (distribution == "GGX") - BSDF = Color * (Fr * microfacet_ggx(Normal, Roughness, eta) + + BSDF = Color * (Fr * microfacet_ggx(Normal, Roughness) + (1.0 - Fr) * microfacet_ggx_refraction(Normal, Roughness, eta)); } diff --git a/intern/cycles/kernel/osl/nodes/node_glossy_bsdf.osl b/intern/cycles/kernel/shaders/node_glossy_bsdf.osl index 48d61ea0ab5..03340c74af5 100644 --- a/intern/cycles/kernel/osl/nodes/node_glossy_bsdf.osl +++ b/intern/cycles/kernel/shaders/node_glossy_bsdf.osl @@ -29,9 +29,9 @@ shader node_glossy_bsdf( if (distribution == "Sharp") BSDF = Color * reflection(Normal); else if (distribution == "Beckmann") - BSDF = Color * microfacet_beckmann(Normal, Roughness, 1.0); + BSDF = Color * microfacet_beckmann(Normal, Roughness); else if (distribution == "GGX") - BSDF = Color * microfacet_ggx(Normal, Roughness, 1.0); + BSDF = Color * microfacet_ggx(Normal, Roughness); } diff --git a/intern/cycles/kernel/osl/nodes/node_gradient_texture.osl b/intern/cycles/kernel/shaders/node_gradient_texture.osl index ae7cfa51f59..ae7cfa51f59 100644 --- a/intern/cycles/kernel/osl/nodes/node_gradient_texture.osl +++ b/intern/cycles/kernel/shaders/node_gradient_texture.osl diff --git a/intern/cycles/kernel/osl/nodes/node_holdout.osl b/intern/cycles/kernel/shaders/node_holdout.osl index aede50c7ca0..aede50c7ca0 100644 --- a/intern/cycles/kernel/osl/nodes/node_holdout.osl +++ b/intern/cycles/kernel/shaders/node_holdout.osl diff --git a/intern/cycles/kernel/osl/nodes/node_hsv.osl b/intern/cycles/kernel/shaders/node_hsv.osl index 8fd7a1612e8..8fd7a1612e8 100644 --- a/intern/cycles/kernel/osl/nodes/node_hsv.osl +++ b/intern/cycles/kernel/shaders/node_hsv.osl diff --git a/intern/cycles/kernel/osl/nodes/node_image_texture.osl b/intern/cycles/kernel/shaders/node_image_texture.osl index 6393605e6b5..6393605e6b5 100644 --- a/intern/cycles/kernel/osl/nodes/node_image_texture.osl +++ b/intern/cycles/kernel/shaders/node_image_texture.osl diff --git a/intern/cycles/kernel/osl/nodes/node_invert.osl b/intern/cycles/kernel/shaders/node_invert.osl index 27021942558..27021942558 100644 --- a/intern/cycles/kernel/osl/nodes/node_invert.osl +++ b/intern/cycles/kernel/shaders/node_invert.osl diff --git a/intern/cycles/kernel/osl/nodes/node_layer_weight.osl b/intern/cycles/kernel/shaders/node_layer_weight.osl index 3ea57f71786..3ea57f71786 100644 --- a/intern/cycles/kernel/osl/nodes/node_layer_weight.osl +++ b/intern/cycles/kernel/shaders/node_layer_weight.osl diff --git a/intern/cycles/kernel/osl/nodes/node_light_falloff.osl b/intern/cycles/kernel/shaders/node_light_falloff.osl index 3877b6d5bdc..7ffa6fe0ffb 100644 --- a/intern/cycles/kernel/osl/nodes/node_light_falloff.osl +++ b/intern/cycles/kernel/shaders/node_light_falloff.osl @@ -27,7 +27,7 @@ shader node_light_falloff( { float ray_length = 0.0; float strength = Strength; - getattribute("std::ray_length", ray_length); + getattribute("path:ray_length", ray_length); if (Smooth > 0.0) { float squared = ray_length*ray_length; diff --git a/intern/cycles/kernel/osl/nodes/node_light_path.osl b/intern/cycles/kernel/shaders/node_light_path.osl index ca92a5e6553..9e3f6c7b4a9 100644 --- a/intern/cycles/kernel/osl/nodes/node_light_path.osl +++ b/intern/cycles/kernel/shaders/node_light_path.osl @@ -36,6 +36,6 @@ shader node_light_path( IsReflectionRay = raytype("reflection"); IsTransmissionRay = raytype("refraction"); - getattribute("std::ray_length", RayLength); + getattribute("path:ray_length", RayLength); } diff --git a/intern/cycles/kernel/osl/nodes/node_magic_texture.osl b/intern/cycles/kernel/shaders/node_magic_texture.osl index e464b83bc9e..e464b83bc9e 100644 --- a/intern/cycles/kernel/osl/nodes/node_magic_texture.osl +++ b/intern/cycles/kernel/shaders/node_magic_texture.osl diff --git a/intern/cycles/kernel/osl/nodes/node_mapping.osl b/intern/cycles/kernel/shaders/node_mapping.osl index 2e720edfc7e..2e720edfc7e 100644 --- a/intern/cycles/kernel/osl/nodes/node_mapping.osl +++ b/intern/cycles/kernel/shaders/node_mapping.osl diff --git a/intern/cycles/kernel/osl/nodes/node_math.osl b/intern/cycles/kernel/shaders/node_math.osl index 24dce898fd2..24dce898fd2 100644 --- a/intern/cycles/kernel/osl/nodes/node_math.osl +++ b/intern/cycles/kernel/shaders/node_math.osl diff --git a/intern/cycles/kernel/osl/nodes/node_mix.osl b/intern/cycles/kernel/shaders/node_mix.osl index 69e68e5ed15..69e68e5ed15 100644 --- a/intern/cycles/kernel/osl/nodes/node_mix.osl +++ b/intern/cycles/kernel/shaders/node_mix.osl diff --git a/intern/cycles/kernel/osl/nodes/node_mix_closure.osl b/intern/cycles/kernel/shaders/node_mix_closure.osl index e28dd1fc436..e28dd1fc436 100644 --- a/intern/cycles/kernel/osl/nodes/node_mix_closure.osl +++ b/intern/cycles/kernel/shaders/node_mix_closure.osl diff --git a/intern/cycles/kernel/osl/nodes/node_musgrave_texture.osl b/intern/cycles/kernel/shaders/node_musgrave_texture.osl index 71461b8fd79..71461b8fd79 100644 --- a/intern/cycles/kernel/osl/nodes/node_musgrave_texture.osl +++ b/intern/cycles/kernel/shaders/node_musgrave_texture.osl diff --git a/intern/cycles/kernel/osl/nodes/node_noise_texture.osl b/intern/cycles/kernel/shaders/node_noise_texture.osl index 227b2bf8cea..227b2bf8cea 100644 --- a/intern/cycles/kernel/osl/nodes/node_noise_texture.osl +++ b/intern/cycles/kernel/shaders/node_noise_texture.osl diff --git a/intern/cycles/kernel/osl/nodes/node_normal.osl b/intern/cycles/kernel/shaders/node_normal.osl index d5f16acb88c..d5f16acb88c 100644 --- a/intern/cycles/kernel/osl/nodes/node_normal.osl +++ b/intern/cycles/kernel/shaders/node_normal.osl diff --git a/intern/cycles/kernel/osl/nodes/node_object_info.osl b/intern/cycles/kernel/shaders/node_object_info.osl index 0d503258179..c3b1ff29f09 100644 --- a/intern/cycles/kernel/osl/nodes/node_object_info.osl +++ b/intern/cycles/kernel/shaders/node_object_info.osl @@ -24,9 +24,9 @@ shader node_object_info( output float MaterialIndex = 0.0, output float Random = 0.0) { - getattribute("std::object_location", Location); - getattribute("std::object_index", ObjectIndex); - getattribute("std::material_index", MaterialIndex); - getattribute("std::object_random", Random); + getattribute("object:location", Location); + getattribute("object:index", ObjectIndex); + getattribute("material:index", MaterialIndex); + getattribute("object:random", Random); } diff --git a/intern/cycles/kernel/osl/nodes/node_output_displacement.osl b/intern/cycles/kernel/shaders/node_output_displacement.osl index 5649b879c5b..5649b879c5b 100644 --- a/intern/cycles/kernel/osl/nodes/node_output_displacement.osl +++ b/intern/cycles/kernel/shaders/node_output_displacement.osl diff --git a/intern/cycles/kernel/osl/nodes/node_output_surface.osl b/intern/cycles/kernel/shaders/node_output_surface.osl index 6efaf91121b..6efaf91121b 100644 --- a/intern/cycles/kernel/osl/nodes/node_output_surface.osl +++ b/intern/cycles/kernel/shaders/node_output_surface.osl diff --git a/intern/cycles/kernel/osl/nodes/node_output_volume.osl b/intern/cycles/kernel/shaders/node_output_volume.osl index 18094242dc7..18094242dc7 100644 --- a/intern/cycles/kernel/osl/nodes/node_output_volume.osl +++ b/intern/cycles/kernel/shaders/node_output_volume.osl diff --git a/intern/cycles/kernel/osl/nodes/node_particle_info.osl b/intern/cycles/kernel/shaders/node_particle_info.osl index ba51ccbd953..5e59ad1a990 100644 --- a/intern/cycles/kernel/osl/nodes/node_particle_info.osl +++ b/intern/cycles/kernel/shaders/node_particle_info.osl @@ -27,12 +27,12 @@ shader node_particle_info( output vector Velocity = point(0.0, 0.0, 0.0), output vector AngularVelocity = point(0.0, 0.0, 0.0)) { - getattribute("std::particle_index", Index); - getattribute("std::particle_age", Age); - getattribute("std::particle_lifetime", Lifetime); - getattribute("std::particle_location", Location); - getattribute("std::particle_size", Size); - getattribute("std::particle_velocity", Velocity); - getattribute("std::particle_angular_velocity", AngularVelocity); + getattribute("particle:index", Index); + getattribute("particle:age", Age); + getattribute("particle:lifetime", Lifetime); + getattribute("particle:location", Location); + getattribute("particle:size", Size); + getattribute("particle:velocity", Velocity); + getattribute("particle:angular_velocity", AngularVelocity); } diff --git a/intern/cycles/kernel/osl/nodes/node_rgb_ramp.osl b/intern/cycles/kernel/shaders/node_rgb_ramp.osl index a128ebbd1cf..a128ebbd1cf 100644 --- a/intern/cycles/kernel/osl/nodes/node_rgb_ramp.osl +++ b/intern/cycles/kernel/shaders/node_rgb_ramp.osl diff --git a/intern/cycles/kernel/osl/nodes/node_separate_rgb.osl b/intern/cycles/kernel/shaders/node_separate_rgb.osl index b48bd7e59d6..b48bd7e59d6 100644 --- a/intern/cycles/kernel/osl/nodes/node_separate_rgb.osl +++ b/intern/cycles/kernel/shaders/node_separate_rgb.osl diff --git a/intern/cycles/kernel/osl/nodes/node_set_normal.osl b/intern/cycles/kernel/shaders/node_set_normal.osl index 27a4b2f5b8b..27a4b2f5b8b 100644 --- a/intern/cycles/kernel/osl/nodes/node_set_normal.osl +++ b/intern/cycles/kernel/shaders/node_set_normal.osl diff --git a/intern/cycles/kernel/osl/nodes/node_sky_texture.osl b/intern/cycles/kernel/shaders/node_sky_texture.osl index 932fb1e2f17..932fb1e2f17 100644 --- a/intern/cycles/kernel/osl/nodes/node_sky_texture.osl +++ b/intern/cycles/kernel/shaders/node_sky_texture.osl diff --git a/intern/cycles/kernel/osl/nodes/node_texture.h b/intern/cycles/kernel/shaders/node_texture.h index 1b3ba8207ab..1b3ba8207ab 100644 --- a/intern/cycles/kernel/osl/nodes/node_texture.h +++ b/intern/cycles/kernel/shaders/node_texture.h diff --git a/intern/cycles/kernel/osl/nodes/node_texture_coordinate.osl b/intern/cycles/kernel/shaders/node_texture_coordinate.osl index 405ed118c2b..791838dfffe 100644 --- a/intern/cycles/kernel/osl/nodes/node_texture_coordinate.osl +++ b/intern/cycles/kernel/shaders/node_texture_coordinate.osl @@ -44,12 +44,12 @@ shader node_texture_coordinate( } else { if (from_dupli) { - getattribute("std::dupli_generated", Generated); - getattribute("std::dupli_uv", UV); + getattribute("geom:dupli_generated", Generated); + getattribute("geom:dupli_uv", UV); } else { - getattribute("std::generated", Generated); - getattribute("std::uv", UV); + getattribute("geom:generated", Generated); + getattribute("geom:uv", UV); } Object = transform("object", P); diff --git a/intern/cycles/kernel/osl/nodes/node_translucent_bsdf.osl b/intern/cycles/kernel/shaders/node_translucent_bsdf.osl index e7efe73700c..e7efe73700c 100644 --- a/intern/cycles/kernel/osl/nodes/node_translucent_bsdf.osl +++ b/intern/cycles/kernel/shaders/node_translucent_bsdf.osl diff --git a/intern/cycles/kernel/osl/nodes/node_transparent_bsdf.osl b/intern/cycles/kernel/shaders/node_transparent_bsdf.osl index 875bce3f16c..875bce3f16c 100644 --- a/intern/cycles/kernel/osl/nodes/node_transparent_bsdf.osl +++ b/intern/cycles/kernel/shaders/node_transparent_bsdf.osl diff --git a/intern/cycles/kernel/osl/nodes/node_value.osl b/intern/cycles/kernel/shaders/node_value.osl index bee6f39f2bc..bee6f39f2bc 100644 --- a/intern/cycles/kernel/osl/nodes/node_value.osl +++ b/intern/cycles/kernel/shaders/node_value.osl diff --git a/intern/cycles/kernel/osl/nodes/node_vector_math.osl b/intern/cycles/kernel/shaders/node_vector_math.osl index f22a6e8441a..f22a6e8441a 100644 --- a/intern/cycles/kernel/osl/nodes/node_vector_math.osl +++ b/intern/cycles/kernel/shaders/node_vector_math.osl diff --git a/intern/cycles/kernel/osl/nodes/node_velvet_bsdf.osl b/intern/cycles/kernel/shaders/node_velvet_bsdf.osl index 4bb4e39a1ba..3aa662bdd08 100644 --- a/intern/cycles/kernel/osl/nodes/node_velvet_bsdf.osl +++ b/intern/cycles/kernel/shaders/node_velvet_bsdf.osl @@ -27,6 +27,6 @@ shader node_velvet_bsdf( { float sigma = clamp(Sigma, 0.0, 1.0); - BSDF = Color * ashikhmin_velvet(Normal, sigma, 1.0); + BSDF = Color * ashikhmin_velvet(Normal, sigma); } diff --git a/intern/cycles/kernel/osl/nodes/node_voronoi_texture.osl b/intern/cycles/kernel/shaders/node_voronoi_texture.osl index a44df00a267..a44df00a267 100644 --- a/intern/cycles/kernel/osl/nodes/node_voronoi_texture.osl +++ b/intern/cycles/kernel/shaders/node_voronoi_texture.osl diff --git a/intern/cycles/kernel/osl/nodes/node_ward_bsdf.osl b/intern/cycles/kernel/shaders/node_ward_bsdf.osl index e204be123b8..e204be123b8 100644 --- a/intern/cycles/kernel/osl/nodes/node_ward_bsdf.osl +++ b/intern/cycles/kernel/shaders/node_ward_bsdf.osl diff --git a/intern/cycles/kernel/osl/nodes/node_wave_texture.osl b/intern/cycles/kernel/shaders/node_wave_texture.osl index 79b8a8885d1..79b8a8885d1 100644 --- a/intern/cycles/kernel/osl/nodes/node_wave_texture.osl +++ b/intern/cycles/kernel/shaders/node_wave_texture.osl diff --git a/intern/cycles/kernel/osl/nodes/oslutil.h b/intern/cycles/kernel/shaders/oslutil.h index 6c91684d9a6..6c91684d9a6 100644 --- a/intern/cycles/kernel/osl/nodes/oslutil.h +++ b/intern/cycles/kernel/shaders/oslutil.h diff --git a/intern/cycles/kernel/osl/nodes/stdosl.h b/intern/cycles/kernel/shaders/stdosl.h index e5accf4eb54..4237291c7a4 100644 --- a/intern/cycles/kernel/osl/nodes/stdosl.h +++ b/intern/cycles/kernel/shaders/stdosl.h @@ -434,81 +434,18 @@ string concat (string a, string b, string c, string d, string e, string f) { closure color diffuse(normal N) BUILTIN; closure color oren_nayar(normal N, float sigma) BUILTIN; closure color translucent(normal N) BUILTIN; -closure color reflection(normal N, float eta) BUILTIN; -closure color reflection(normal N) { return reflection (N, 0.0); } +closure color reflection(normal N) BUILTIN; closure color refraction(normal N, float eta) BUILTIN; -closure color dielectric(normal N, float eta) BUILTIN; closure color transparent() BUILTIN; -closure color microfacet_ggx(normal N, float ag, float eta) BUILTIN; +closure color microfacet_ggx(normal N, float ag) BUILTIN; closure color microfacet_ggx_refraction(normal N, float ag, float eta) BUILTIN; -closure color microfacet_beckmann(normal N, float ab, float eta) BUILTIN; +closure color microfacet_beckmann(normal N, float ab) BUILTIN; closure color microfacet_beckmann_refraction(normal N, float ab, float eta) BUILTIN; closure color ward(normal N, vector T,float ax, float ay) BUILTIN; -closure color phong(normal N, float exponent) BUILTIN; -closure color phong_ramp(normal N, float exponent, color colors[8]) BUILTIN; -closure color hair_diffuse(vector T) BUILTIN; -closure color hair_specular(vector T, float offset, float exponent) BUILTIN; -closure color ashikhmin_velvet(normal N, float sigma, float eta) BUILTIN; -closure color westin_backscatter(normal N, float roughness) BUILTIN; -closure color westin_sheen(normal N, float edginess) BUILTIN; -closure color bssrdf_cubic(color radius) BUILTIN; -closure color emission(float inner_angle, float outer_angle) BUILTIN; -closure color emission(float outer_angle) BUILTIN; +closure color ashikhmin_velvet(normal N, float sigma) BUILTIN; closure color emission() BUILTIN; -closure color debug(string tag) BUILTIN; closure color background() BUILTIN; closure color holdout() BUILTIN; -closure color subsurface(float eta, float g, color mfp, color albedo) BUILTIN; - -closure color cloth(normal N, float s, float t, float dsdx, float dtdx, float dsdy, float dtdy, - float area_scaled, vector dPdu, color diff_warp_col, color diff_weft_col, - color spec_warp_col, color spec_weft_col, float fresnel_warp, float fresnel_weft, - float spread_x_mult, float spread_y_mult, int pattern, float pattern_angle, - float warp_width_scale, float weft_width_scale, float thread_count_mult_u, - float thread_count_mult_v) BUILTIN; -closure color cloth_specular(normal N, color spec_col[4], float eta[4], int thread_pattern[4], - float pattern_weight[4], int current_thread, float brdf_interp, - float btf_interp, float uux, float vvx, float area_scaled, vector dPdu, - float eccentricity[4], float angle[4], float Kx[4], float Ky[4], - float Sx[4], float Sy[4]) BUILTIN; -closure color fakefur_diffuse(normal N, vector T, float fur_reflectivity, float fur_transmission, - float shadow_start, float shadow_end, float fur_attenuation, float fur_density, - float fur_avg_radius, float fur_length, float fur_shadow_fraction) BUILTIN; -closure color fakefur_specular(normal N, vector T, float offset, float exp, float fur_reflectivity, - float fur_transmission, float shadow_start, float shadow_end, - float fur_attenuation, float fur_density, float fur_avg_radius, - float fur_length, float fur_shadow_fraction) BUILTIN; - -closure color fakefur_skin(vector N, vector T, float fur_reflectivity, float fur_transmission, - float shadow_start, float shadow_end, float fur_attenuation, float fur_density, - float fur_avg_radius, float fur_length) BUILTIN; - - -closure color cloth(normal N, float s, float t, color diff_warp, color diff_weft, - color spec_warp, color spec_weft, float fresnel_warp, float fresnel_weft, - float spread_x_mult, float spread_y_mult, int pattern, float pattern_angle, - float warp_width_scale, float weft_width_scale, float thread_count_mult_u, - float thread_count_mult_v) -{ - - return cloth(N, s, t, Dx(s), Dx(t), Dy(s), Dy(t), area(P), dPdu, diff_warp, diff_weft, spec_warp, spec_weft, - fresnel_warp, fresnel_weft, spread_x_mult, spread_y_mult, pattern, pattern_angle, - warp_width_scale, weft_width_scale, thread_count_mult_u, thread_count_mult_v); -} - -closure color cloth(normal N, float s, float t, color diff_warp, color diff_weft, - color spec_warp, color spec_weft, float fresnel_warp, float fresnel_weft, - float spread_x_mult, float spread_y_mult, int pattern, float pattern_angle, - float warp_width_scale, float weft_width_scale, float thread_count_mult_u, - float thread_count_mult_v, string tok, string val) -{ - - return cloth(N, s, t, Dx(s), Dx(t), Dy(s), Dy(t), area(P), dPdu, diff_warp, diff_weft, spec_warp, spec_weft, - fresnel_warp, fresnel_weft, spread_x_mult, spread_y_mult, pattern, pattern_angle, - warp_width_scale, weft_width_scale, thread_count_mult_u, thread_count_mult_v, tok, val); -} - - // Renderer state int raytype (string typename) BUILTIN; diff --git a/intern/cycles/kernel/svm/svm_geometry.h b/intern/cycles/kernel/svm/svm_geometry.h index e0f9e337652..501fed95002 100644 --- a/intern/cycles/kernel/svm/svm_geometry.h +++ b/intern/cycles/kernel/svm/svm_geometry.h @@ -49,7 +49,7 @@ __device void svm_node_geometry(KernelGlobals *kg, ShaderData *sd, float *stack, int attr_offset = find_attribute(kg, sd, ATTR_STD_TANGENT); if(attr_offset != ATTR_STD_NOT_FOUND) { - data = triangle_attribute_float3(kg, sd, ATTR_ELEMENT_VERTEX, attr_offset, NULL, NULL); + data = triangle_attribute_float3(kg, sd, ATTR_ELEMENT_CORNER, attr_offset, NULL, NULL); object_normal_transform(kg, sd, &data); } else { diff --git a/intern/cycles/render/attribute.cpp b/intern/cycles/render/attribute.cpp index 4bcaef0fb17..c7a9ab3e51a 100644 --- a/intern/cycles/render/attribute.cpp +++ b/intern/cycles/render/attribute.cpp @@ -163,7 +163,7 @@ Attribute *AttributeSet::add(AttributeStandard std, ustring name) else if(std == ATTR_STD_UV) attr = add(name, TypeDesc::TypePoint, Attribute::CORNER); else if(std == ATTR_STD_TANGENT) - attr = add(name, TypeDesc::TypeVector, Attribute::VERTEX); + attr = add(name, TypeDesc::TypeVector, Attribute::CORNER); else if(std == ATTR_STD_GENERATED) attr = add(name, TypeDesc::TypePoint, Attribute::VERTEX); else if(std == ATTR_STD_POSITION_UNDEFORMED) diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp index 3c41b4f1ad3..13c06a922cc 100644 --- a/intern/cycles/render/mesh.cpp +++ b/intern/cycles/render/mesh.cpp @@ -366,8 +366,8 @@ void MeshManager::update_osl_attributes(Device *device, Scene *scene, vector<Att osl_attr.type = TypeDesc::TypeColor; if(req.std != ATTR_STD_NONE) { - /* if standard attribute, add lookup by std:: name convention */ - ustring stdname(std::string("std::") + std::string(attribute_standard_name(req.std))); + /* if standard attribute, add lookup by geom: name convention */ + ustring stdname(string("geom:") + string(attribute_standard_name(req.std))); og->attribute_map[i][stdname] = osl_attr; } else if(req.name != ustring()) { diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index 2cdab3a6560..42ab3fe17aa 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -2922,5 +2922,25 @@ void SetNormalNode::compile(OSLCompiler& compiler) compiler.add(this, "node_set_normal"); } +/* OSLScriptNode */ + +OSLScriptNode::OSLScriptNode() +: ShaderNode("osl_script") +{ +} + +void OSLScriptNode::compile(SVMCompiler& compiler) +{ + /* doesn't work for SVM, obviously ... */ +} + +void OSLScriptNode::compile(OSLCompiler& compiler) +{ + if(!filepath.empty()) + compiler.add(this, filepath.c_str(), true); + else + compiler.add(this, bytecode_hash.c_str(), false); +} + CCL_NAMESPACE_END diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h index fbc61e12fd4..0508bf6b266 100644 --- a/intern/cycles/render/nodes.h +++ b/intern/cycles/render/nodes.h @@ -445,6 +445,18 @@ public: SHADER_NODE_CLASS(SetNormalNode) }; +class OSLScriptNode : public ShaderNode { +public: + SHADER_NODE_CLASS(OSLScriptNode) + string filepath; + string bytecode_hash; + + /* ShaderInput/ShaderOutput only stores a shallow string copy (const char *)! + * The actual socket names have to be stored externally to avoid memory errors. */ + vector<ustring> input_names; + vector<ustring> output_names; +}; + CCL_NAMESPACE_END #endif /* __NODES_H__ */ diff --git a/intern/cycles/render/osl.cpp b/intern/cycles/render/osl.cpp index 638bfa8634e..a8a40a4e596 100644 --- a/intern/cycles/render/osl.cpp +++ b/intern/cycles/render/osl.cpp @@ -31,6 +31,7 @@ #include "osl_shader.h" #include "util_foreach.h" +#include "util_md5.h" #include "util_path.h" #include "util_progress.h" @@ -46,36 +47,8 @@ OSLShaderManager::OSLShaderManager() { services = new OSLRenderServices(); - /* if we let OSL create it, it leaks */ - ts = TextureSystem::create(true); - ts->attribute("automip", 1); - ts->attribute("autotile", 64); - - ss = OSL::ShadingSystem::create(services, ts, &errhandler); - ss->attribute("lockgeom", 1); - ss->attribute("commonspace", "world"); - ss->attribute("optimize", 2); - //ss->attribute("debug", 1); - //ss->attribute("statistics:level", 1); - ss->attribute("searchpath:shader", path_get("shader").c_str()); - - /* our own ray types */ - static const char *raytypes[] = { - "camera", /* PATH_RAY_CAMERA */ - "reflection", /* PATH_RAY_REFLECT */ - "refraction", /* PATH_RAY_TRANSMIT */ - "diffuse", /* PATH_RAY_DIFFUSE */ - "glossy", /* PATH_RAY_GLOSSY */ - "singular", /* PATH_RAY_SINGULAR */ - "transparent", /* PATH_RAY_TRANSPARENT */ - "shadow", /* PATH_RAY_SHADOW_OPAQUE */ - "shadow", /* PATH_RAY_SHADOW_TRANSPARENT */ - }; - - const int nraytypes = sizeof(raytypes)/sizeof(raytypes[0]); - ss->attribute("raytypes", TypeDesc(TypeDesc::STRING, nraytypes), raytypes); - - OSLShader::register_closures(ss); + shading_system_init(); + texture_system_init(); } OSLShaderManager::~OSLShaderManager() @@ -87,18 +60,14 @@ OSLShaderManager::~OSLShaderManager() void OSLShaderManager::device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress) { - /* test if we need to update */ - bool need_update = false; - - foreach(Shader *shader, scene->shaders) - if(shader->need_update) - need_update = true; - if(!need_update) return; device_free(device, dscene); + /* determine which shaders are in use */ + device_update_shaders_used(scene); + /* create shaders */ OSLGlobals *og = (OSLGlobals*)device->osl_memory(); @@ -110,7 +79,7 @@ void OSLShaderManager::device_update(Device *device, DeviceScene *dscene, Scene if(shader->sample_as_light && shader->has_surface_emission) scene->light_manager->need_update = true; - OSLCompiler compiler((void*)ss); + OSLCompiler compiler((void*)this, (void*)ss); compiler.background = (shader == scene->shaders[scene->default_background]); compiler.compile(og, shader); } @@ -126,6 +95,8 @@ void OSLShaderManager::device_update(Device *device, DeviceScene *dscene, Scene foreach(Shader *shader, scene->shaders) shader->need_update = false; + + need_update = false; /* set texture system */ scene->image_manager->set_osl_texture_system((void*)ts); @@ -151,10 +122,165 @@ void OSLShaderManager::device_free(Device *device, DeviceScene *dscene) og->background_state.reset(); } +void OSLShaderManager::texture_system_init() +{ + /* if we let OSL create it, it leaks */ + ts = TextureSystem::create(true); + ts->attribute("automip", 1); + ts->attribute("autotile", 64); + + /* effectively unlimited for now, until we support proper mipmap lookups */ + ts->attribute("max_memory_MB", 16384); +} + +void OSLShaderManager::shading_system_init() +{ + ss = OSL::ShadingSystem::create(services, ts, &errhandler); + ss->attribute("lockgeom", 1); + ss->attribute("commonspace", "world"); + ss->attribute("optimize", 2); + //ss->attribute("debug", 1); + //ss->attribute("statistics:level", 1); + ss->attribute("searchpath:shader", path_get("shader")); + + /* our own ray types */ + static const char *raytypes[] = { + "camera", /* PATH_RAY_CAMERA */ + "reflection", /* PATH_RAY_REFLECT */ + "refraction", /* PATH_RAY_TRANSMIT */ + "diffuse", /* PATH_RAY_DIFFUSE */ + "glossy", /* PATH_RAY_GLOSSY */ + "singular", /* PATH_RAY_SINGULAR */ + "transparent", /* PATH_RAY_TRANSPARENT */ + "shadow", /* PATH_RAY_SHADOW_OPAQUE */ + "shadow", /* PATH_RAY_SHADOW_TRANSPARENT */ + }; + + const int nraytypes = sizeof(raytypes)/sizeof(raytypes[0]); + ss->attribute("raytypes", TypeDesc(TypeDesc::STRING, nraytypes), raytypes); + + OSLShader::register_closures(ss); + + loaded_shaders.clear(); +} + +bool OSLShaderManager::osl_compile(const string& inputfile, const string& outputfile) +{ + vector<string> options; + string stdosl_path; + + /* specify output file name */ + options.push_back("-o"); + options.push_back(outputfile); + + /* specify standard include path */ + options.push_back("-I" + path_get("shader")); + stdosl_path = path_get("shader/stdosl.h"); + + /* compile */ + OSL::OSLCompiler *compiler = OSL::OSLCompiler::create(); + bool ok = compiler->compile(inputfile, options, stdosl_path); + delete compiler; + + return ok; +} + +bool OSLShaderManager::osl_query(OSL::OSLQuery& query, const string& filepath) +{ + string searchpath = path_user_get("shaders"); + return query.open(filepath, searchpath); +} + +static string shader_filepath_hash(const string& filepath, uint64_t modified_time) +{ + /* compute a hash from filepath and modified time to detect changes */ + MD5Hash md5; + md5.append((const uint8_t*)filepath.c_str(), filepath.size()); + md5.append((const uint8_t*)&modified_time, sizeof(modified_time)); + + return md5.get_hex(); +} + +const char *OSLShaderManager::shader_test_loaded(const string& hash) +{ + set<string>::iterator it = loaded_shaders.find(hash); + return (it == loaded_shaders.end())? NULL: it->c_str(); +} + +const char *OSLShaderManager::shader_load_filepath(string filepath) +{ + size_t len = filepath.size(); + string extension = filepath.substr(len - 4); + uint64_t modified_time = path_modified_time(filepath); + + if(extension == ".osl") { + /* .OSL File */ + string osopath = filepath.substr(0, len - 4) + ".oso"; + uint64_t oso_modified_time = path_modified_time(osopath); + + /* test if we have loaded the corresponding .OSO already */ + if(oso_modified_time != 0) { + const char *hash = shader_test_loaded(shader_filepath_hash(osopath, oso_modified_time)); + + if(hash) + return hash; + } + + /* autocompile .OSL to .OSO if needed */ + if(oso_modified_time == 0 || (oso_modified_time < modified_time)) { + OSLShaderManager::osl_compile(filepath, osopath); + modified_time = path_modified_time(osopath); + } + else + modified_time = oso_modified_time; + + filepath = osopath; + } + else { + if(extension == ".oso") { + /* .OSO File, nothing to do */ + } + else if(path_dirname(filepath) == "") { + /* .OSO File in search path */ + filepath = path_join(path_user_get("shaders"), filepath + ".oso"); + } + else { + /* unknown file */ + return NULL; + } + + /* test if we have loaded this .OSO already */ + const char *hash = shader_test_loaded(shader_filepath_hash(filepath, modified_time)); + + if(hash) + return hash; + } + + /* read oso bytecode from file */ + string bytecode_hash = shader_filepath_hash(filepath, modified_time); + string bytecode; + + if(!path_read_text(filepath, bytecode)) { + fprintf(stderr, "Cycles shader graph: failed to read file %s\n", filepath.c_str()); + loaded_shaders.insert(bytecode_hash); /* to avoid repeat tries */ + return NULL; + } + + return shader_load_bytecode(bytecode_hash, bytecode); +} + +const char *OSLShaderManager::shader_load_bytecode(const string& hash, const string& bytecode) +{ + ss->LoadMemoryShader(hash.c_str(), bytecode.c_str()); + + return loaded_shaders.insert(hash).first->c_str(); +} + /* Graph Compiler */ -OSLCompiler::OSLCompiler(void *shadingsys_) +OSLCompiler::OSLCompiler(void *manager_, void *shadingsys_) { + manager = manager_; shadingsys = shadingsys_; current_type = SHADER_TYPE_SURFACE; current_shader = NULL; @@ -235,10 +361,18 @@ bool OSLCompiler::node_skip_input(ShaderNode *node, ShaderInput *input) return false; } -void OSLCompiler::add(ShaderNode *node, const char *name) +void OSLCompiler::add(ShaderNode *node, const char *name, bool isfilepath) { OSL::ShadingSystem *ss = (OSL::ShadingSystem*)shadingsys; + /* load filepath */ + if(isfilepath) { + name = ((OSLShaderManager*)manager)->shader_load_filepath(name); + + if(name == NULL) + return; + } + /* pass in fixed parameter values */ foreach(ShaderInput *input, node->inputs) { if(!input->link) { @@ -507,82 +641,85 @@ void OSLCompiler::compile_type(Shader *shader, ShaderGraph *graph, ShaderType ty void OSLCompiler::compile(OSLGlobals *og, Shader *shader) { - OSL::ShadingSystem *ss = (OSL::ShadingSystem*)shadingsys; - ShaderGraph *graph = shader->graph; - ShaderNode *output = (graph)? graph->output(): NULL; + if(shader->need_update) { + OSL::ShadingSystem *ss = (OSL::ShadingSystem*)shadingsys; + ShaderGraph *graph = shader->graph; + ShaderNode *output = (graph)? graph->output(): NULL; - /* copy graph for shader with bump mapping */ - if(output->input("Surface")->link && output->input("Displacement")->link) - if(!shader->graph_bump) - shader->graph_bump = shader->graph->copy(); + /* copy graph for shader with bump mapping */ + if(output->input("Surface")->link && output->input("Displacement")->link) + if(!shader->graph_bump) + shader->graph_bump = shader->graph->copy(); - /* finalize */ - shader->graph->finalize(false, true); - if(shader->graph_bump) - shader->graph_bump->finalize(true, true); + /* finalize */ + shader->graph->finalize(false, true); + if(shader->graph_bump) + shader->graph_bump->finalize(true, true); - current_shader = shader; + current_shader = shader; - shader->has_surface = false; - shader->has_surface_emission = false; - shader->has_surface_transparent = false; - shader->has_volume = false; - shader->has_displacement = false; + shader->has_surface = false; + shader->has_surface_emission = false; + shader->has_surface_transparent = false; + shader->has_volume = false; + shader->has_displacement = false; - /* generate surface shader */ - if(graph && output->input("Surface")->link) { - compile_type(shader, shader->graph, SHADER_TYPE_SURFACE); - og->surface_state.push_back(ss->state()); + /* generate surface shader */ + if(shader->used && graph && output->input("Surface")->link) { + compile_type(shader, shader->graph, SHADER_TYPE_SURFACE); + shader->osl_surface_ref = ss->state(); + + if(shader->graph_bump) { + ss->clear_state(); + compile_type(shader, shader->graph_bump, SHADER_TYPE_SURFACE); + } - if(shader->graph_bump) { + shader->osl_surface_bump_ref = ss->state(); ss->clear_state(); - compile_type(shader, shader->graph_bump, SHADER_TYPE_SURFACE); - og->surface_state.push_back(ss->state()); - } - else - og->surface_state.push_back(ss->state()); - ss->clear_state(); + shader->has_surface = true; + } + else { + shader->osl_surface_ref = OSL::ShadingAttribStateRef(); + shader->osl_surface_bump_ref = OSL::ShadingAttribStateRef(); + } - shader->has_surface = true; - } - else { - og->surface_state.push_back(OSL::ShadingAttribStateRef()); - og->surface_state.push_back(OSL::ShadingAttribStateRef()); - } + /* generate volume shader */ + if(shader->used && graph && output->input("Volume")->link) { + compile_type(shader, shader->graph, SHADER_TYPE_VOLUME); + shader->has_volume = true; - /* generate volume shader */ - if(graph && output->input("Volume")->link) { - compile_type(shader, shader->graph, SHADER_TYPE_VOLUME); - shader->has_volume = true; + shader->osl_volume_ref = ss->state(); + ss->clear_state(); + } + else + shader->osl_volume_ref = OSL::ShadingAttribStateRef(); - og->volume_state.push_back(ss->state()); - og->volume_state.push_back(ss->state()); - ss->clear_state(); - } - else { - og->volume_state.push_back(OSL::ShadingAttribStateRef()); - og->volume_state.push_back(OSL::ShadingAttribStateRef()); + /* generate displacement shader */ + if(shader->used && graph && output->input("Displacement")->link) { + compile_type(shader, shader->graph, SHADER_TYPE_DISPLACEMENT); + shader->has_displacement = true; + shader->osl_displacement_ref = ss->state(); + ss->clear_state(); + } + else + shader->osl_displacement_ref = OSL::ShadingAttribStateRef(); } - /* generate displacement shader */ - if(graph && output->input("Displacement")->link) { - compile_type(shader, shader->graph, SHADER_TYPE_DISPLACEMENT); - shader->has_displacement = true; + /* push state to array for lookup */ + og->surface_state.push_back(shader->osl_surface_ref); + og->surface_state.push_back(shader->osl_surface_bump_ref); - og->displacement_state.push_back(ss->state()); - og->displacement_state.push_back(ss->state()); - ss->clear_state(); - } - else { - og->displacement_state.push_back(OSL::ShadingAttribStateRef()); - og->displacement_state.push_back(OSL::ShadingAttribStateRef()); - } + og->volume_state.push_back(shader->osl_volume_ref); + og->volume_state.push_back(shader->osl_volume_ref); + + og->displacement_state.push_back(shader->osl_displacement_ref); + og->displacement_state.push_back(shader->osl_displacement_ref); } #else -void OSLCompiler::add(ShaderNode *node, const char *name) +void OSLCompiler::add(ShaderNode *node, const char *name, bool isfilepath) { } diff --git a/intern/cycles/render/osl.h b/intern/cycles/render/osl.h index 90107a34a98..cee37c58d74 100644 --- a/intern/cycles/render/osl.h +++ b/intern/cycles/render/osl.h @@ -20,11 +20,14 @@ #define __OSL_H__ #include "util_set.h" +#include "util_string.h" #include "shader.h" #ifdef WITH_OSL +#include <OSL/oslcomp.h> #include <OSL/oslexec.h> +#include <OSL/oslquery.h> #endif CCL_NAMESPACE_BEGIN @@ -52,11 +55,24 @@ public: void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress); void device_free(Device *device, DeviceScene *dscene); -private: + /* osl compile and query */ + static bool osl_compile(const string& inputfile, const string& outputfile); + static bool osl_query(OSL::OSLQuery& query, const string& filepath); + + /* shader file loading, all functions return pointer to hash string if found */ + const char *shader_test_loaded(const string& hash); + const char *shader_load_bytecode(const string& hash, const string& bytecode); + const char *shader_load_filepath(string filepath); + +protected: + void texture_system_init(); + void shading_system_init(); + OSL::ShadingSystem *ss; OSL::TextureSystem *ts; OSLRenderServices *services; OSL::ErrorHandler errhandler; + set<string> loaded_shaders; }; #endif @@ -65,10 +81,10 @@ private: class OSLCompiler { public: - OSLCompiler(void *shadingsys); + OSLCompiler(void *manager, void *shadingsys); void compile(OSLGlobals *og, Shader *shader); - void add(ShaderNode *node, const char *name); + void add(ShaderNode *node, const char *name, bool isfilepath = false); void parameter(const char *name, float f); void parameter_color(const char *name, float3 f); @@ -104,6 +120,7 @@ private: void generate_nodes(const set<ShaderNode*>& nodes); void *shadingsys; + void *manager; ShaderType current_type; Shader *current_shader; }; diff --git a/intern/cycles/render/shader.cpp b/intern/cycles/render/shader.cpp index fae1d6bd81c..17f7fbd43d6 100644 --- a/intern/cycles/render/shader.cpp +++ b/intern/cycles/render/shader.cpp @@ -49,6 +49,8 @@ Shader::Shader() has_volume = false; has_displacement = false; + used = false; + need_update = true; need_update_attributes = true; } @@ -98,6 +100,16 @@ void Shader::tag_update(Scene *scene) } } +void Shader::tag_used(Scene *scene) +{ + /* if an unused shader suddenly gets used somewhere, it needs to be + * recompiled because it was skipped for compilation before */ + if(!used) { + need_update = true; + scene->shader_manager->need_update = true; + } +} + /* Shader Manager */ ShaderManager::ShaderManager() @@ -161,6 +173,27 @@ int ShaderManager::get_shader_id(uint shader, Mesh *mesh, bool smooth) return id; } +void ShaderManager::device_update_shaders_used(Scene *scene) +{ + /* figure out which shaders are in use, so SVM/OSL can skip compiling them + * for speed and avoid loading image textures into memory */ + foreach(Shader *shader, scene->shaders) + shader->used = false; + + scene->shaders[scene->default_surface]->used = true; + scene->shaders[scene->default_light]->used = true; + scene->shaders[scene->default_background]->used = true; + scene->shaders[scene->default_holdout]->used = true; + scene->shaders[scene->default_empty]->used = true; + + foreach(Mesh *mesh, scene->meshes) + foreach(uint shader, mesh->used_shaders) + scene->shaders[shader]->used = true; + + foreach(Light *light, scene->lights) + scene->shaders[light->shader]->used = true; +} + void ShaderManager::device_update_common(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress) { device_free_common(device, dscene); diff --git a/intern/cycles/render/shader.h b/intern/cycles/render/shader.h index 02788008060..373b3356f51 100644 --- a/intern/cycles/render/shader.h +++ b/intern/cycles/render/shader.h @@ -27,6 +27,10 @@ #include "util_string.h" #include "util_types.h" +#ifdef WITH_OSL +#include <OSL/oslexec.h> +#endif + CCL_NAMESPACE_BEGIN class Device; @@ -75,11 +79,23 @@ public: /* requested mesh attributes */ AttributeRequestSet attributes; + /* determined before compiling */ + bool used; + +#ifdef WITH_OSL + /* osl shading state references */ + OSL::ShadingAttribStateRef osl_surface_ref; + OSL::ShadingAttribStateRef osl_surface_bump_ref; + OSL::ShadingAttribStateRef osl_volume_ref; + OSL::ShadingAttribStateRef osl_displacement_ref; +#endif + Shader(); ~Shader(); void set_graph(ShaderGraph *graph); void tag_update(Scene *scene); + void tag_used(Scene *scene); }; /* Shader Manager virtual base class @@ -98,6 +114,7 @@ public: virtual void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress) = 0; virtual void device_free(Device *device, DeviceScene *dscene) = 0; + void device_update_shaders_used(Scene *scene); void device_update_common(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress); void device_free_common(Device *device, DeviceScene *dscene); diff --git a/intern/cycles/render/svm.cpp b/intern/cycles/render/svm.cpp index c41d503b217..dc249984499 100644 --- a/intern/cycles/render/svm.cpp +++ b/intern/cycles/render/svm.cpp @@ -48,6 +48,9 @@ void SVMShaderManager::device_update(Device *device, DeviceScene *dscene, Scene /* test if we need to update */ device_free(device, dscene); + /* determine which shaders are in use */ + device_update_shaders_used(scene); + /* svm_nodes */ vector<int4> svm_nodes; size_t i; @@ -609,36 +612,38 @@ void SVMCompiler::compile_type(Shader *shader, ShaderGraph *graph, ShaderType ty output->stack_offset = SVM_STACK_INVALID; } - if(clin->link) { - bool generate = false; - if(type == SHADER_TYPE_SURFACE) { - /* generate surface shader */ - generate = true; - shader->has_surface = true; - } - else if(type == SHADER_TYPE_VOLUME) { - /* generate volume shader */ - generate = true; - shader->has_volume = true; - } - else if(type == SHADER_TYPE_DISPLACEMENT) { - /* generate displacement shader */ - generate = true; - shader->has_displacement = true; - } + if(shader->used) { + if(clin->link) { + bool generate = false; + if(type == SHADER_TYPE_SURFACE) { + /* generate surface shader */ + generate = true; + shader->has_surface = true; + } + else if(type == SHADER_TYPE_VOLUME) { + /* generate volume shader */ + generate = true; + shader->has_volume = true; + } + else if(type == SHADER_TYPE_DISPLACEMENT) { + /* generate displacement shader */ + generate = true; + shader->has_displacement = true; + } - if(generate) { - set<ShaderNode*> done; + if(generate) { + set<ShaderNode*> done; - if(use_multi_closure) - generate_multi_closure(clin->link->parent, done, SVM_STACK_INVALID); - else - generate_closure(clin->link->parent, done); + if(use_multi_closure) + generate_multi_closure(clin->link->parent, done, SVM_STACK_INVALID); + else + generate_closure(clin->link->parent, done); + } } - } - /* compile output node */ - node->compile(*this); + /* compile output node */ + node->compile(*this); + } add_node(NODE_END, 0, 0, 0); } diff --git a/intern/cycles/util/util_md5.h b/intern/cycles/util/util_md5.h index 43e08e64f39..aab177d9fe6 100644 --- a/intern/cycles/util/util_md5.h +++ b/intern/cycles/util/util_md5.h @@ -44,7 +44,7 @@ public: bool append_file(const string& filepath); string get_hex(); - protected: +protected: void process(const uint8_t *data); void finish(uint8_t digest[16]); diff --git a/intern/cycles/util/util_path.cpp b/intern/cycles/util/util_path.cpp index a571fe81118..8cf23bc6a76 100644 --- a/intern/cycles/util/util_path.cpp +++ b/intern/cycles/util/util_path.cpp @@ -170,7 +170,7 @@ bool path_read_binary(const string& path, vector<uint8_t>& binary) return true; } -static bool path_read_text(const string& path, string& text) +bool path_read_text(const string& path, string& text) { vector<uint8_t> binary; @@ -184,6 +184,14 @@ static bool path_read_text(const string& path, string& text) return true; } +uint64_t path_modified_time(const string& path) +{ + if(boost::filesystem::exists(path)) + return (uint64_t)boost::filesystem::last_write_time(path); + + return 0; +} + string path_source_replace_includes(const string& source_, const string& path) { /* our own little c preprocessor that replaces #includes with the file diff --git a/intern/cycles/util/util_path.h b/intern/cycles/util/util_path.h index 6cba6a3158f..89e4452ecd9 100644 --- a/intern/cycles/util/util_path.h +++ b/intern/cycles/util/util_path.h @@ -45,6 +45,9 @@ string path_files_md5_hash(const string& dir); void path_create_directories(const string& path); bool path_write_binary(const string& path, const vector<uint8_t>& binary); bool path_read_binary(const string& path, vector<uint8_t>& binary); +bool path_read_text(const string& path, string& text); + +uint64_t path_modified_time(const string& path); string path_source_replace_includes(const string& source, const string& path); diff --git a/intern/ffmpeg/ffmpeg_compat.h b/intern/ffmpeg/ffmpeg_compat.h index 2fd61570011..37cde2c2837 100644 --- a/intern/ffmpeg/ffmpeg_compat.h +++ b/intern/ffmpeg/ffmpeg_compat.h @@ -110,7 +110,7 @@ void av_update_cur_dts(AVFormatContext *s, AVStream *ref_st, int64_t timestamp) #endif /* there are some version inbetween, which have avio_... functions but no - AVIO_FLAG_... */ + * AVIO_FLAG_... */ #ifndef AVIO_FLAG_WRITE #define AVIO_FLAG_WRITE URL_WRONLY #endif diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm index 7c3e2f35ac9..27720a01a3f 100644 --- a/intern/ghost/intern/GHOST_SystemCocoa.mm +++ b/intern/ghost/intern/GHOST_SystemCocoa.mm @@ -1159,7 +1159,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleDraggingEvent(GHOST_TEventType eventType NSEnumerator *enumerator; NSImageRep *representation; - ibuf = IMB_allocImBuf (imgSize.width , imgSize.height, 32, IB_rect); + ibuf = IMB_allocImBuf (imgSize.width, imgSize.height, 32, IB_rect); if (!ibuf) { [droppedImg release]; return GHOST_kFailure; diff --git a/intern/itasc/CMakeLists.txt b/intern/itasc/CMakeLists.txt index 55879e85cdf..99c64d956cb 100644 --- a/intern/itasc/CMakeLists.txt +++ b/intern/itasc/CMakeLists.txt @@ -125,7 +125,6 @@ set(SRC ../../extern/Eigen3/Eigen/src/Cholesky/LLT.h ../../extern/Eigen3/Eigen/src/Cholesky/LLT_MKL.h ../../extern/Eigen3/Eigen/src/CholmodSupport/CholmodSupport.h - ../../extern/Eigen3/Eigen/src/Core/arch ../../extern/Eigen3/Eigen/src/Core/Array.h ../../extern/Eigen3/Eigen/src/Core/ArrayBase.h ../../extern/Eigen3/Eigen/src/Core/ArrayWrapper.h @@ -167,7 +166,6 @@ set(SRC ../../extern/Eigen3/Eigen/src/Core/PlainObjectBase.h ../../extern/Eigen3/Eigen/src/Core/Product.h ../../extern/Eigen3/Eigen/src/Core/ProductBase.h - ../../extern/Eigen3/Eigen/src/Core/products ../../extern/Eigen3/Eigen/src/Core/Random.h ../../extern/Eigen3/Eigen/src/Core/Redux.h ../../extern/Eigen3/Eigen/src/Core/Replicate.h @@ -183,14 +181,9 @@ set(SRC ../../extern/Eigen3/Eigen/src/Core/Transpose.h ../../extern/Eigen3/Eigen/src/Core/Transpositions.h ../../extern/Eigen3/Eigen/src/Core/TriangularMatrix.h - ../../extern/Eigen3/Eigen/src/Core/util ../../extern/Eigen3/Eigen/src/Core/VectorBlock.h ../../extern/Eigen3/Eigen/src/Core/VectorwiseOp.h ../../extern/Eigen3/Eigen/src/Core/Visitor.h - ../../extern/Eigen3/Eigen/src/Core/arch/AltiVec - ../../extern/Eigen3/Eigen/src/Core/arch/Default - ../../extern/Eigen3/Eigen/src/Core/arch/NEON - ../../extern/Eigen3/Eigen/src/Core/arch/SSE ../../extern/Eigen3/Eigen/src/Core/arch/AltiVec/Complex.h ../../extern/Eigen3/Eigen/src/Core/arch/AltiVec/PacketMath.h ../../extern/Eigen3/Eigen/src/Core/arch/Default/Settings.h @@ -236,7 +229,6 @@ set(SRC ../../extern/Eigen3/Eigen/src/Eigen2Support/Block.h ../../extern/Eigen3/Eigen/src/Eigen2Support/Cwise.h ../../extern/Eigen3/Eigen/src/Eigen2Support/CwiseOperators.h - ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry ../../extern/Eigen3/Eigen/src/Eigen2Support/Lazy.h ../../extern/Eigen3/Eigen/src/Eigen2Support/LeastSquares.h ../../extern/Eigen3/Eigen/src/Eigen2Support/LU.h @@ -274,7 +266,6 @@ set(SRC ../../extern/Eigen3/Eigen/src/Eigenvalues/Tridiagonalization.h ../../extern/Eigen3/Eigen/src/Geometry/AlignedBox.h ../../extern/Eigen3/Eigen/src/Geometry/AngleAxis.h - ../../extern/Eigen3/Eigen/src/Geometry/arch ../../extern/Eigen3/Eigen/src/Geometry/EulerAngles.h ../../extern/Eigen3/Eigen/src/Geometry/Homogeneous.h ../../extern/Eigen3/Eigen/src/Geometry/Hyperplane.h @@ -297,7 +288,6 @@ set(SRC ../../extern/Eigen3/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h ../../extern/Eigen3/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h ../../extern/Eigen3/Eigen/src/Jacobi/Jacobi.h - ../../extern/Eigen3/Eigen/src/LU/arch ../../extern/Eigen3/Eigen/src/LU/Determinant.h ../../extern/Eigen3/Eigen/src/LU/FullPivLU.h ../../extern/Eigen3/Eigen/src/LU/Inverse.h diff --git a/intern/smoke/intern/smoke_API.cpp b/intern/smoke/intern/smoke_API.cpp index 3dce804c543..6011de0bddb 100644 --- a/intern/smoke/intern/smoke_API.cpp +++ b/intern/smoke/intern/smoke_API.cpp @@ -386,7 +386,7 @@ extern "C" float *smoke_turbulence_get_flame(WTURBULENCE *wt) extern "C" void smoke_turbulence_get_res(WTURBULENCE *wt, int *res) { - if(wt) { + if (wt) { Vec3Int r = wt->getResBig(); res[0] = r[0]; res[1] = r[1]; @@ -396,9 +396,9 @@ extern "C" void smoke_turbulence_get_res(WTURBULENCE *wt, int *res) extern "C" int smoke_turbulence_get_cells(WTURBULENCE *wt) { - if(wt) { + if (wt) { Vec3Int r = wt->getResBig(); - return r[0]*r[1]*r[2]; + return r[0] * r[1] * r[2]; } return 0; } diff --git a/intern/utfconv/utfconv.h b/intern/utfconv/utfconv.h index 3bfd2772991..cf0e69170a2 100644 --- a/intern/utfconv/utfconv.h +++ b/intern/utfconv/utfconv.h @@ -95,7 +95,7 @@ wchar_t *alloc_utf16_from_8(const char *in8, size_t add); wchar_t *in8str ## _16 = alloc_utf16_from_8((char *)in8str, 0) #define UTF16_UN_ENCODE(in8str) \ - free(in8str ## _16); } (void)0 + free(in8str ## _16); } (void)0 #ifdef __cplusplus } diff --git a/release/scripts/modules/bl_i18n_utils/settings.py b/release/scripts/modules/bl_i18n_utils/settings.py index 4bfcee9c583..0db3f85f1ff 100644 --- a/release/scripts/modules/bl_i18n_utils/settings.py +++ b/release/scripts/modules/bl_i18n_utils/settings.py @@ -40,46 +40,46 @@ LANGUAGES_CATEGORIES = ( ) LANGUAGES = ( # ID, UI english label, ISO code. - ( 0, "Default (Default)", "DEFAULT"), - ( 1, "English (English)", "en_US"), - ( 2, "Japanese (日本語)", "ja_JP"), - ( 3, "Dutch (Nederlandse taal)", "nl_NL"), - ( 4, "Italian (Italiano)", "it_IT"), - ( 5, "German (Deutsch)", "de_DE"), - ( 6, "Finnish (Suomi)", "fi_FI"), - ( 7, "Swedish (Svenska)", "sv_SE"), - ( 8, "French (Français)", "fr_FR"), - ( 9, "Spanish (Español)", "es"), - (10, "Catalan (Català)", "ca_AD"), - (11, "Czech (Český)", "cs_CZ"), - (12, "Portuguese (Português)", "pt_PT"), - (13, "Simplified Chinese (简体中文)", "zh_CN"), - (14, "Traditional Chinese (繁體中文)", "zh_TW"), - (15, "Russian (Русский)", "ru_RU"), - (16, "Croatian (Hrvatski)", "hr_HR"), - (17, "Serbian (Српски)", "sr_RS"), - (18, "Ukrainian (Український)", "uk_UA"), - (19, "Polish (Polski)", "pl_PL"), - (20, "Romanian (Român)", "ro_RO"), # XXX No po's yet. + ( 0, "Default (Default)", "DEFAULT", ""), + ( 1, "English (English)", "en_US", "english"), + ( 2, "Japanese (日本語)", "ja_JP", "japanese"), + ( 3, "Dutch (Nederlandse taal)", "nl_NL", "dutch"), + ( 4, "Italian (Italiano)", "it_IT", "italian"), + ( 5, "German (Deutsch)", "de_DE", "german"), + ( 6, "Finnish (Suomi)", "fi_FI", "finnish"), + ( 7, "Swedish (Svenska)", "sv_SE", "swedish"), + ( 8, "French (Français)", "fr_FR", "french"), + ( 9, "Spanish (Español)", "es", "spanish"), + (10, "Catalan (Català)", "ca_AD", "catalan"), + (11, "Czech (Český)", "cs_CZ", "czech"), + (12, "Portuguese (Português)", "pt_PT", "portuguese_portugal"), + (13, "Simplified Chinese (简体中文)", "zh_CN", "Chinese (Simplified)_China.1252"), + (14, "Traditional Chinese (繁體中文)", "zh_TW", "Chinese (Traditional)_China.1252"), + (15, "Russian (Русский)", "ru_RU", "russian"), + (16, "Croatian (Hrvatski)", "hr_HR", "croatian"), + (17, "Serbian (Српски)", "sr_RS", "serbian"), + (18, "Ukrainian (Український)", "uk_UA", "ukrainian"), + (19, "Polish (Polski)", "pl_PL", "polish"), + (20, "Romanian (Român)", "ro_RO", "romanian"), # Using the utf8 flipped form of Arabic (العربية). - (21, "Arabic (ﺔﻴﺑﺮﻌﻟﺍ)", "ar_EG"), - (22, "Bulgarian (Български)", "bg_BG"), - (23, "Greek (Ελληνικά)", "el_GR"), - (24, "Korean (한국 언어)", "ko_KR"), # XXX No po's yet. - (25, "Nepali (नेपाली)", "ne_NP"), + (21, "Arabic (ﺔﻴﺑﺮﻌﻟﺍ)", "ar_EG", "arabic"), + (22, "Bulgarian (Български)", "bg_BG", "bulgarian"), + (23, "Greek (Ελληνικά)", "el_GR", "greek"), + (24, "Korean (한국 언어)", "ko_KR", "korean"), + (25, "Nepali (नेपाली)", "ne_NP", "nepali"), # Using the utf8 flipped form of Persian (فارسی). - (26, "Persian (ﯽﺳﺭﺎﻓ)", "fa_IR"), - (27, "Indonesian (Bahasa indonesia)", "id_ID"), - (28, "Serbian Latin (Srpski latinica)", "sr_RS@latin"), - (29, "Kyrgyz (Кыргыз тили)", "ky_KG"), - (30, "Turkish (Türkçe)", "tr_TR"), - (31, "Hungarian (Magyar)", "hu_HU"), - (32, "Brazilian Portuguese (Português do Brasil)", "pt_BR"), + (26, "Persian (ﯽﺳﺭﺎﻓ)", "fa_IR", "farsi"), + (27, "Indonesian (Bahasa indonesia)", "id_ID", "indonesian"), + (28, "Serbian Latin (Srpski latinica)", "sr_RS@latin", "serbian (latin)"), + (29, "Kyrgyz (Кыргыз тили)", "ky_KG", "kyrgyz"), + (30, "Turkish (Türkçe)", "tr_TR", "turkish"), + (31, "Hungarian (Magyar)", "hu_HU", "hungarian"), + (32, "Brazilian Portuguese (Português do Brasil)", "pt_BR", "protuguese_brazil"), # Using the utf8 flipped form of Hebrew (עִבְרִית)). - (33, "Hebrew (תירִבְעִ)", "he_IL"), - (34, "Estonian (Eestlane)", "et_EE"), - (35, "Esperanto (Esperanto)", "eo"), - (36, "Spanish from Spain (Español de España)", "es_ES"), + (33, "Hebrew (תירִבְעִ)", "he_IL", "hebrew"), + (34, "Estonian (Eestlane)", "et_EE", "estonian"), + (35, "Esperanto (Esperanto)", "eo", "esperanto"), + (36, "Spanish from Spain (Español de España)", "es_ES", "spanish_spain"), ) # Name of language file used by Blender to generate translations' menu. diff --git a/release/scripts/modules/bl_i18n_utils/update_languages_menu.py b/release/scripts/modules/bl_i18n_utils/update_languages_menu.py index 5eeeb152af7..d45a5543220 100755 --- a/release/scripts/modules/bl_i18n_utils/update_languages_menu.py +++ b/release/scripts/modules/bl_i18n_utils/update_languages_menu.py @@ -53,7 +53,7 @@ FLAG_MESSAGES = { def find_matching_po(languages, stats, forbidden): """Match languages defined in LANGUAGES setting to relevant po, if possible!""" ret = [] - for uid, label, org_key in languages: + for uid, label, org_key, long_loc in languages: key = org_key if key not in stats: # Try to simplify the key (eg from es_ES to es). @@ -64,11 +64,11 @@ def find_matching_po(languages, stats, forbidden): key = key + org_key[org_key.index('@'):] if key in stats: if key in forbidden: - ret.append((stats[key], uid, label, org_key, FORBIDDEN)) + ret.append((stats[key], uid, label, org_key, long_loc, FORBIDDEN)) else: - ret.append((stats[key], uid, label, org_key, OK)) + ret.append((stats[key], uid, label, org_key, long_loc, OK)) else: - ret.append((0.0, uid, label, org_key, MISSING)) + ret.append((0.0, uid, label, org_key, long_loc, MISSING)) return ret def main(): @@ -103,14 +103,14 @@ def main(): stats = sorted(stats, key=lambda it: it[0], reverse=True) langs_cats = [[] for i in range(len(limits))] highest_uid = 0 - for prop, uid, label, key, flag in stats: + for prop, uid, label, key, long_loc, flag in stats: if prop < limits[idx][0]: # Sub-sort languages by iso-codes. langs_cats[idx].sort(key=lambda it: it[2]) idx += 1 if prop < min_trans and flag == OK: flag = TOOLOW - langs_cats[idx].append((uid, label, key, flag)) + langs_cats[idx].append((uid, label, key, long_loc, flag)) if abs(uid) > highest_uid: highest_uid = abs(uid) # Sub-sort last group of languages by iso-codes! @@ -120,7 +120,7 @@ def main(): f.write("# and to generate translation menu.\n") f.write("#\n") f.write("# File format:\n") - f.write("# ID:MENULABEL:ISOCODE\n") + f.write("# ID:MENULABEL:ISOCODE:WINCODE\n") f.write("# ID must be unique, except for 0 value (marks categories for menu).\n") f.write("# Line starting with a # are comments!\n") f.write("#\n") @@ -130,17 +130,17 @@ def main(): f.write("#\n") # Write "category menu label"... if langs_cat: - f.write("0:{}:\n".format(cat[1])) + f.write("0:{}::\n".format(cat[1])) else: # Do not write the category if it has no language! f.write("# Void category! #0:{}:\n".format(cat[1])) # ...and all matching language entries! - for uid, label, key, flag in langs_cat: + for uid, label, key, long_loc, flag in langs_cat: if flag == OK: - f.write("{}:{}:{}\n".format(uid, label, key)) + f.write("{}:{}:{}:{}\n".format(uid, label, key, long_loc)) else: # Non-existing, commented entry! - f.write("# {} #{}:{}:{}\n".format(FLAG_MESSAGES[flag], uid, label, key)) + f.write("# {} #{}:{}:{}:{}\n".format(FLAG_MESSAGES[flag], uid, label, key, long_loc)) if __name__ == "__main__": diff --git a/release/scripts/startup/bl_operators/presets.py b/release/scripts/startup/bl_operators/presets.py index 5482912345d..b7adf53dbf1 100644 --- a/release/scripts/startup/bl_operators/presets.py +++ b/release/scripts/startup/bl_operators/presets.py @@ -185,10 +185,12 @@ class ExecutePreset(Operator): filepath = StringProperty( subtype='FILE_PATH', + options={'SKIP_SAVE'}, ) menu_idname = StringProperty( name="Menu ID Name", description="ID name of the menu this was called from", + options={'SKIP_SAVE'}, ) def execute(self, context): @@ -504,7 +506,7 @@ class AddPresetKeyconfig(AddPresetBase, Operator): class AddPresetOperator(AddPresetBase, Operator): - """Add an Application Interaction Preset""" + """Add an Operator Preset""" bl_idname = "wm.operator_preset_add" bl_label = "Operator Preset" preset_menu = "WM_MT_operator_presets" @@ -512,7 +514,7 @@ class AddPresetOperator(AddPresetBase, Operator): operator = StringProperty( name="Operator", maxlen=64, - options={'HIDDEN'}, + options={'HIDDEN', 'SKIP_SAVE'}, ) preset_defines = [ diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py index 5cc041476c9..2bff11a686d 100644 --- a/release/scripts/startup/bl_operators/wm.py +++ b/release/scripts/startup/bl_operators/wm.py @@ -1290,7 +1290,7 @@ class WM_OT_blenderplayer_start(Operator): return {'CANCELLED'} filepath = os.path.join(bpy.app.tempdir, "game.blend") - bpy.ops.wm.save_as_mainfile(filepath=filepath, check_existing=False, copy=True) + bpy.ops.wm.save_as_mainfile('EXEC_DEFAULT', filepath=filepath, copy=True) subprocess.call([player_path, filepath]) return {'FINISHED'} diff --git a/release/scripts/startup/bl_ui/properties_data_lamp.py b/release/scripts/startup/bl_ui/properties_data_lamp.py index 769715ef1b9..71fdc1d7b67 100644 --- a/release/scripts/startup/bl_ui/properties_data_lamp.py +++ b/release/scripts/startup/bl_ui/properties_data_lamp.py @@ -118,7 +118,7 @@ class DATA_PT_lamp(DataButtonsPanel, Panel): class DATA_PT_sunsky(DataButtonsPanel, Panel): bl_label = "Sky & Atmosphere" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + COMPAT_ENGINES = {'BLENDER_RENDER'} @classmethod def poll(cls, context): diff --git a/release/scripts/startup/bl_ui/properties_game.py b/release/scripts/startup/bl_ui/properties_game.py index 5ff49a7d369..bf0c9eb762a 100644 --- a/release/scripts/startup/bl_ui/properties_game.py +++ b/release/scripts/startup/bl_ui/properties_game.py @@ -190,6 +190,14 @@ class PHYSICS_PT_game_physics(PhysicsButtonsPanel, Panel): layout.operator("mesh.navmesh_reset") layout.operator("mesh.navmesh_clear") + if physics_type not in {'NO_COLLISION', 'OCCLUDE'}: + layout.separator() + split = layout.split() + + col = split.column() + col.prop(game, "collision_group") + col = split.column() + col.prop(game, "collision_mask") class PHYSICS_PT_game_collision_bounds(PhysicsButtonsPanel, Panel): bl_label = "Collision Bounds" diff --git a/release/scripts/startup/bl_ui/properties_render.py b/release/scripts/startup/bl_ui/properties_render.py index 33ce0e07f17..aa7d78225d5 100644 --- a/release/scripts/startup/bl_ui/properties_render.py +++ b/release/scripts/startup/bl_ui/properties_render.py @@ -228,11 +228,13 @@ class RENDER_PT_performance(RenderButtonsPanel, Panel): split = layout.split() col = split.column() - col.label(text="Threads:") - col.row().prop(rd, "threads_mode", expand=True) - sub = col.column() - sub.enabled = rd.threads_mode == 'FIXED' - sub.prop(rd, "threads") + sub = col.column(align=True) + sub.label(text="Threads:") + sub.row().prop(rd, "threads_mode", expand=True) + subsub = sub.column() + subsub.enabled = rd.threads_mode == 'FIXED' + subsub.prop(rd, "threads") + sub = col.column(align=True) sub.label(text="Tiles:") sub.prop(rd, "parts_x", text="X") diff --git a/release/scripts/startup/bl_ui/space_info.py b/release/scripts/startup/bl_ui/space_info.py index 9ab2a772df0..c0f2d3c361b 100644 --- a/release/scripts/startup/bl_ui/space_info.py +++ b/release/scripts/startup/bl_ui/space_info.py @@ -112,8 +112,9 @@ class INFO_MT_file(Menu): layout.separator() - layout.operator_context = 'INVOKE_AREA' - layout.operator("wm.save_mainfile", text="Save", icon='FILE_TICK').check_existing = False + layout.operator_context = 'EXEC_AREA' if context.blend_data.is_saved else 'INVOKE_AREA' + layout.operator("wm.save_mainfile", text="Save", icon='FILE_TICK') + layout.operator_context = 'INVOKE_AREA' layout.operator("wm.save_as_mainfile", text="Save As...", icon='SAVE_AS') layout.operator_context = 'INVOKE_AREA' diff --git a/release/scripts/startup/bl_ui/space_node.py b/release/scripts/startup/bl_ui/space_node.py index 5b7ecbfb618..c46b1c20738 100644 --- a/release/scripts/startup/bl_ui/space_node.py +++ b/release/scripts/startup/bl_ui/space_node.py @@ -166,11 +166,19 @@ class NODE_MT_node(Menu): layout.operator("node.delete_reconnect") layout.separator() + + layout.operator("node.join", text="Join in new Frame") + layout.operator("node.detach", text="Remove from Frame") + + layout.separator() + layout.operator("node.link_make") layout.operator("node.link_make", text="Make and Replace Links").replace = True layout.operator("node.links_cut") + layout.operator("node.links_detach") layout.separator() + layout.operator("node.group_edit") layout.operator("node.group_ungroup") layout.operator("node.group_make") diff --git a/release/scripts/startup/bl_ui/space_text.py b/release/scripts/startup/bl_ui/space_text.py index eca9bc22db9..8a853a09199 100644 --- a/release/scripts/startup/bl_ui/space_text.py +++ b/release/scripts/startup/bl_ui/space_text.py @@ -56,12 +56,17 @@ class TEXT_HT_header(Header): row.prop(st, "show_syntax_highlight", text="") if text: - row = layout.row() - row.operator("text.run_script") + osl = text.name.endswith(".osl") or text.name.endswith(".oso") - row = layout.row() - row.active = text.name.endswith(".py") - row.prop(text, "use_module") + if osl: + row = layout.row() + row.operator("node.shader_script_update") + else: + row = layout.row() + row.operator("text.run_script") + + row = layout.row() + row.prop(text, "use_module") row = layout.row() if text.filepath: diff --git a/release/scripts/startup/bl_ui/space_userpref_keymap.py b/release/scripts/startup/bl_ui/space_userpref_keymap.py index da498268b9b..81d67aa662c 100644 --- a/release/scripts/startup/bl_ui/space_userpref_keymap.py +++ b/release/scripts/startup/bl_ui/space_userpref_keymap.py @@ -186,10 +186,10 @@ class InputKeyMapPanel: sub = split.column() subrow = sub.row(align=True) - if map_type in {'KEYBOARD', 'NDOF'}: + if map_type == 'KEYBOARD': subrow.prop(kmi, "type", text="", event=True) subrow.prop(kmi, "value", text="") - elif map_type == 'MOUSE': + elif map_type in {'MOUSE', 'NDOF'}: subrow.prop(kmi, "type", text="") subrow.prop(kmi, "value", text="") diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 65e5b529487..5d949e89caa 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -571,7 +571,7 @@ class VIEW3D_MT_select_edit_mesh(Menu): layout.separator() layout.operator("mesh.select_random", text="Random") - layout.operator("mesh.select_nth", text="Every N Number of Verts") + layout.operator("mesh.select_nth") layout.operator("mesh.edges_select_sharp", text="Sharp Edges") layout.operator("mesh.faces_select_linked_flat", text="Linked Flat Faces") layout.operator("mesh.select_interior_faces", text="Interior Faces") @@ -579,7 +579,7 @@ class VIEW3D_MT_select_edit_mesh(Menu): layout.separator() - layout.operator("mesh.select_by_number_vertices", text="By Number of Verts") + layout.operator("mesh.select_face_by_sides") if context.scene.tool_settings.mesh_select_mode[2] is False: layout.operator("mesh.select_non_manifold", text="Non Manifold") layout.operator("mesh.select_loose_verts", text="Loose Verts/Edges") @@ -968,8 +968,9 @@ class VIEW3D_MT_object_parent(Menu): def draw(self, context): layout = self.layout - layout.operator_menu_enum("object.parent_set", "type", text="Set") - layout.operator_menu_enum("object.parent_clear", "type", text="Clear") + layout.operator_enum("object.parent_set", "type") + layout.separator() + layout.operator_enum("object.parent_clear", "type") class VIEW3D_MT_object_track(Menu): @@ -978,8 +979,9 @@ class VIEW3D_MT_object_track(Menu): def draw(self, context): layout = self.layout - layout.operator_menu_enum("object.track_set", "type", text="Set") - layout.operator_menu_enum("object.track_clear", "type", text="Clear") + layout.operator_enum("object.track_set", "type") + layout.separator() + layout.operator_enum("object.track_clear", "type") class VIEW3D_MT_object_group(Menu): @@ -1951,10 +1953,6 @@ class VIEW3D_MT_edit_mesh_dissolve(Menu): layout.separator() - layout.operator_enum("mesh.dissolve", "type") - - layout.separator() - layout.operator("mesh.dissolve_limited") diff --git a/source/blender/blenfont/intern/blf_lang.c b/source/blender/blenfont/intern/blf_lang.c index 9f4cf72d120..501f8cd2958 100644 --- a/source/blender/blenfont/intern/blf_lang.c +++ b/source/blender/blenfont/intern/blf_lang.c @@ -65,12 +65,14 @@ static char global_language[32]; static char global_encoding_name[32]; static const char **locales = NULL; +static char **long_locales = NULL; /* XXX Temp fix until we get a final solution with modern intl lib under windows! */ static int num_locales = 0; static EnumPropertyItem *locales_menu = NULL; static int num_locales_menu = 0; #define ULANGUAGE ((U.language >= 0 && U.language < num_locales) ? U.language : 0) #define LOCALE(_id) (locales ? locales[_id] : "") +#define LONG_LOCALE(_id) (long_locales ? long_locales[_id] : "") static void free_locales(void) { @@ -81,8 +83,18 @@ static void free_locales(void) MEM_freeN((void*)locales_menu[idx].name); MEM_freeN((void*)locales_menu[idx].description); /* Also frees locales's relevant value! */ } + + idx = num_locales; + while (idx--) { + if (long_locales[idx]) { + MEM_freeN(long_locales[idx]); + } + } + MEM_freeN(locales); locales = NULL; + MEM_freeN(long_locales); + long_locales = NULL; } if (locales_menu) { MEM_freeN(locales_menu); @@ -128,9 +140,10 @@ static void fill_locales(void) /* Do not allocate locales with zero-sized mem, as LOCALE macro uses NULL locales as invalid marker! */ if (num_locales > 0) { locales = MEM_callocN(num_locales * sizeof(char*), __func__); + long_locales = MEM_callocN(num_locales * sizeof(char*), __func__); while (line) { int id; - char *loc, *sep1, *sep2; + char *loc, *sep1, *sep2, *sep3; str = (char*) line->link; if (str[0] == '#' || str[0] == '\0') { @@ -144,23 +157,32 @@ static void fill_locales(void) sep1++; sep2 = strchr(sep1, ':'); if (sep2) { + locales_menu[idx].value = id; + locales_menu[idx].icon = 0; + locales_menu[idx].name = BLI_strdupn(sep1, sep2 - sep1); + + sep2++; + sep3 = strchr(sep2, ':'); + if (sep3) { + locales_menu[idx].identifier = loc = BLI_strdupn(sep2, sep3 - sep2); - locales_menu[idx].value = id; - locales_menu[idx].icon = 0; - locales_menu[idx].name = BLI_strdupn(sep1, sep2 - sep1); - locales_menu[idx].identifier = loc = BLI_strdup(sep2 + 1); if (id == 0) { /* The DEFAULT item... */ - if (BLI_strnlen(loc, 2)) + if (BLI_strnlen(loc, 2)) { locales[id] = locales_menu[idx].description = BLI_strdup(""); + long_locales[id] = BLI_strdup(""); + } /* Menu "label", not to be stored in locales! */ - else + else { locales_menu[idx].description = BLI_strdup(""); + } } - else + else { locales[id] = locales_menu[idx].description = BLI_strdup(loc); + long_locales[id] = BLI_strdup(sep3 + 1); + } idx++; - + } } } @@ -243,43 +265,39 @@ static void get_language(const char *locale, const char *lang, char *language, c void BLF_lang_set(const char *str) { char *locreturn; - const char *short_locale; int ok = TRUE; int ulang = ULANGUAGE; if ((U.transopts & USER_DOTRANSLATE) == 0) return; - if (str) - short_locale = str; - else - short_locale = LOCALE(ulang); - #if defined(_WIN32) && !defined(FREE_WINDOWS) { - if (short_locale) { + const char *long_locale = str ? str : LONG_LOCALE(ulang); + if (long_locale) { char *envStr; - if (ulang) /* Use system setting. */ + if (ulang) + envStr = BLI_sprintfN("LANG=%s", long_locale); + else /* Use system setting. */ envStr = BLI_sprintfN("LANG=%s", getenv("LANG")); - else - envStr = BLI_sprintfN("LANG=%s", short_locale); gettext_putenv(envStr); MEM_freeN(envStr); } - locreturn = setlocale(LC_ALL, short_locale); + locreturn = setlocale(LC_ALL, long_locale); if (locreturn == NULL) { if (G.debug & G_DEBUG) - printf("Could not change locale to %s\n", short_locale); + printf("Could not change locale to %s\n", long_locale); ok = FALSE; } } #else { + const char *short_locale = str ? str : LOCALE(ulang); static char default_lang[64] = "\0"; static char default_language[64] = "\0"; diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h index fa9223ba6e2..c6c54cc6e8a 100644 --- a/source/blender/blenkernel/BKE_DerivedMesh.h +++ b/source/blender/blenkernel/BKE_DerivedMesh.h @@ -148,6 +148,11 @@ typedef enum DMDrawFlag { typedef enum DMDirtyFlag { /* dm has valid tessellated faces, but tessellated CDDATA need to be updated. */ DM_DIRTY_TESS_CDLAYERS = 1 << 0, + /* One of the MCOL layers have been updated, force updating of GPUDrawObject's colors buffer. + * This is necessary with modern, VBO draw code, as e.g. in vpaint mode me->mcol may be updated + * without actually rebuilding dm (hence by defautl keeping same GPUDrawObject, and same colors + * buffer, which prevents update during a stroke!). */ + DM_DIRTY_MCOL_UPDATE_DRAW = 1 << 1, } DMDirtyFlag; typedef struct DerivedMesh DerivedMesh; @@ -223,6 +228,7 @@ struct DerivedMesh { 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 @@ -231,7 +237,8 @@ struct DerivedMesh { 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*/ CustomData *(*getVertDataLayout)(DerivedMesh * dm); @@ -493,6 +500,7 @@ void DM_add_poly_layer(struct DerivedMesh *dm, int type, int alloctype, void *DM_get_vert_data(struct DerivedMesh *dm, int index, int type); void *DM_get_edge_data(struct DerivedMesh *dm, int index, int type); void *DM_get_tessface_data(struct DerivedMesh *dm, int index, int type); +void *DM_get_poly_data(struct DerivedMesh *dm, int index, int type); /* custom data layer access functions * return pointer to first data layer which matches type (a flat array) @@ -701,4 +709,10 @@ void DM_debug_print(DerivedMesh *dm); void DM_debug_print_cdlayers(CustomData *cdata); #endif +BLI_INLINE int DM_origindex_mface_mpoly(const int *index_mf_to_mpoly, const int *index_mp_to_orig, const int i) +{ + const int j = index_mf_to_mpoly[i]; + return (j != ORIGINDEX_NONE) ? index_mp_to_orig[j] : ORIGINDEX_NONE; +} + #endif diff --git a/source/blender/blenkernel/BKE_colortools.h b/source/blender/blenkernel/BKE_colortools.h index f30cc57bde4..96e05aa87b9 100644 --- a/source/blender/blenkernel/BKE_colortools.h +++ b/source/blender/blenkernel/BKE_colortools.h @@ -63,8 +63,8 @@ void curvemapping_set_black_white(struct CurveMapping *cumap, con #define CURVEMAP_SLOPE_POSITIVE 1 void curvemap_reset(struct CurveMap *cuma, const struct rctf *clipr, int preset, int slope); void curvemap_remove(struct CurveMap *cuma, const short flag); -void curvemap_remove_point(struct CurveMap *cuma, struct CurveMapPoint *cmp); -struct CurveMapPoint *curvemap_insert(struct CurveMap *cuma, float x, float y); +int curvemap_remove_point(struct CurveMap *cuma, struct CurveMapPoint *cmp); +struct CurveMapPoint *curvemap_insert(struct CurveMap *cuma, float x, float y); void curvemap_sethandle(struct CurveMap *cuma, int type); void curvemapping_changed(struct CurveMapping *cumap, int rem_doubles); diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h index e387fc5f97c..4736e7b7312 100644 --- a/source/blender/blenkernel/BKE_customdata.h +++ b/source/blender/blenkernel/BKE_customdata.h @@ -122,7 +122,10 @@ void CustomData_merge(const struct CustomData *source, struct CustomData *dest, void CustomData_bmesh_merge(struct CustomData *source, struct CustomData *dest, CustomDataMask mask, int alloctype, struct BMesh *bm, const char htype); -/* frees data associated with a CustomData object (doesn't free the object +/** NULL's all members and resets the typemap. */ +void CustomData_reset(struct CustomData *data); + +/** frees data associated with a CustomData object (doesn't free the object * itself, though) */ void CustomData_free(struct CustomData *data, int totelem); diff --git a/source/blender/blenkernel/BKE_deform.h b/source/blender/blenkernel/BKE_deform.h index 52a143ddf55..8306da71432 100644 --- a/source/blender/blenkernel/BKE_deform.h +++ b/source/blender/blenkernel/BKE_deform.h @@ -54,6 +54,7 @@ struct MDeformWeight *defvert_verify_index(struct MDeformVert *dv, const int void defvert_add_index_notest(struct MDeformVert *dv, int defgroup, const float weight); void defvert_remove_group(struct MDeformVert *dvert, struct MDeformWeight *dw); void defvert_clear(struct MDeformVert *dvert); +int defvert_find_shared(const struct MDeformVert *dvert_a, const struct MDeformVert *dvert_b); float defvert_find_weight(const struct MDeformVert *dvert, const int defgroup); float defvert_array_find_weight_safe(const struct MDeformVert *dvert, const int index, const int defgroup); diff --git a/source/blender/blenkernel/BKE_idprop.h b/source/blender/blenkernel/BKE_idprop.h index 3cf4a2c5cdc..a9f6a61a655 100644 --- a/source/blender/blenkernel/BKE_idprop.h +++ b/source/blender/blenkernel/BKE_idprop.h @@ -154,6 +154,12 @@ __attribute__((nonnull)) #endif ; +void IDP_MergeGroup(IDProperty *dest, IDProperty *src, const int do_overwrite) +#ifdef __GNUC__ +__attribute__((nonnull)) +#endif +; + /** * This function has a sanity check to make sure ID properties with the same name don't * get added to the group. @@ -260,6 +266,12 @@ __attribute__((nonnull)) #endif ; +int IDP_EqualsProperties_ex(IDProperty *prop1, IDProperty *prop2, const int is_strict) +#ifdef __GNUC__ +__attribute__((warn_unused_result)) +#endif +; + int IDP_EqualsProperties(struct IDProperty *prop1, struct IDProperty *prop2) #ifdef __GNUC__ __attribute__((warn_unused_result)) @@ -306,11 +318,16 @@ void IDP_FreeProperty(struct IDProperty *prop); /** Unlinks any struct IDProperty<->ID linkage that might be going on.*/ void IDP_UnlinkProperty(struct IDProperty *prop); -#define IDP_Int(prop) ((prop)->data.val) -#define IDP_Float(prop) (*(float *)&(prop)->data.val) -#define IDP_String(prop) ((char *)(prop)->data.pointer) -#define IDP_Array(prop) ((prop)->data.pointer) -#define IDP_IDPArray(prop) ((IDProperty *)(prop)->data.pointer) -#define IDP_Double(prop) (*(double *)&(prop)->data.val) +#define IDP_Int(prop) ((prop)->data.val) +#define IDP_Float(prop) (*(float *)&(prop)->data.val) +#define IDP_Double(prop) (*(double *)&(prop)->data.val) +#define IDP_String(prop) ((char *) (prop)->data.pointer) +#define IDP_Array(prop) ((prop)->data.pointer) +#define IDP_IDPArray(prop) ((IDProperty *) (prop)->data.pointer) + +#ifdef DEBUG +/* for printout only */ +void IDP_spit(IDProperty *prop); +#endif #endif /* __BKE_IDPROP_H__ */ diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index cd1875f848b..29e03f66bcc 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -245,6 +245,7 @@ typedef struct bNodeType { #define NODE_CLASS_PARTICLES 25 #define NODE_CLASS_TRANSFORM 30 #define NODE_CLASS_COMBINE 31 +#define NODE_CLASS_SCRIPT 32 #define NODE_CLASS_SHADER 40 #define NODE_CLASS_LAYOUT 100 @@ -551,6 +552,7 @@ struct ShadeResult; #define SH_NODE_PARTICLE_INFO 168 #define SH_NODE_TEX_BRICK 169 #define SH_NODE_BUMP 170 +#define SH_NODE_SCRIPT 171 /* custom defines options for Material node */ #define SH_NODE_MAT_DIFF 1 diff --git a/source/blender/blenkernel/BKE_subsurf.h b/source/blender/blenkernel/BKE_subsurf.h index 3b8d0eafd4d..653f2a42675 100644 --- a/source/blender/blenkernel/BKE_subsurf.h +++ b/source/blender/blenkernel/BKE_subsurf.h @@ -64,10 +64,10 @@ typedef enum { } SubsurfFlags; struct DerivedMesh *subsurf_make_derived_from_derived( - struct DerivedMesh *dm, - struct SubsurfModifierData *smd, - float (*vertCos)[3], - SubsurfFlags flags); + struct DerivedMesh *dm, + struct SubsurfModifierData *smd, + float (*vertCos)[3], + SubsurfFlags flags); void subsurf_calculate_limit_positions(struct Mesh *me, float (*positions_r)[3]); diff --git a/source/blender/blenkernel/BKE_tracking.h b/source/blender/blenkernel/BKE_tracking.h index 167f7bd831a..eb7004b1ced 100644 --- a/source/blender/blenkernel/BKE_tracking.h +++ b/source/blender/blenkernel/BKE_tracking.h @@ -114,7 +114,7 @@ void BKE_tracking_marker_get_subframe_position(struct MovieTrackingTrack *track, /* **** Object **** */ struct MovieTrackingObject *BKE_tracking_object_add(struct MovieTracking *tracking, const char *name); -void BKE_tracking_object_delete(struct MovieTracking *tracking, struct MovieTrackingObject *object); +int BKE_tracking_object_delete(struct MovieTracking *tracking, struct MovieTrackingObject *object); void BKE_tracking_object_unique_name(struct MovieTracking *tracking, struct MovieTrackingObject *object); diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index ddbd4588778..fd92b7b5d69 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -265,9 +265,11 @@ void DM_init_funcs(DerivedMesh *dm) dm->getVertData = DM_get_vert_data; dm->getEdgeData = DM_get_edge_data; dm->getTessFaceData = DM_get_tessface_data; + dm->getPolyData = DM_get_poly_data; dm->getVertDataArray = DM_get_vert_data_layer; dm->getEdgeDataArray = DM_get_edge_data_layer; dm->getTessFaceDataArray = DM_get_tessface_data_layer; + dm->getPolyDataArray = DM_get_poly_data_layer; bvhcache_init(&dm->bvhCache); } @@ -287,6 +289,13 @@ void DM_init(DerivedMesh *dm, DerivedMeshType type, int numVerts, int numEdges, dm->needsFree = 1; dm->auto_bump_scale = -1.0f; dm->dirty = 0; + + /* don't use CustomData_reset(...); because we dont want to touch customdata */ + fill_vn_i(dm->vertData.typemap, CD_NUMTYPES, -1); + fill_vn_i(dm->edgeData.typemap, CD_NUMTYPES, -1); + fill_vn_i(dm->faceData.typemap, CD_NUMTYPES, -1); + fill_vn_i(dm->loopData.typemap, CD_NUMTYPES, -1); + fill_vn_i(dm->polyData.typemap, CD_NUMTYPES, -1); } void DM_from_template(DerivedMesh *dm, DerivedMesh *source, DerivedMeshType type, @@ -383,7 +392,7 @@ void DM_ensure_tessface(DerivedMesh *dm) } else if (dm->dirty & DM_DIRTY_TESS_CDLAYERS) { - BLI_assert(CustomData_has_layer(&dm->faceData, CD_POLYINDEX)); + BLI_assert(CustomData_has_layer(&dm->faceData, CD_ORIGINDEX)); DM_update_tessface_data(dm); } @@ -407,7 +416,7 @@ void DM_update_tessface_data(DerivedMesh *dm) const int hasPCol = CustomData_has_layer(ldata, CD_PREVIEW_MLOOPCOL); const int hasOrigSpace = CustomData_has_layer(ldata, CD_ORIGSPACE_MLOOP); - int *polyindex = CustomData_get_layer(fdata, CD_POLYINDEX); + int *polyindex = CustomData_get_layer(fdata, CD_ORIGINDEX); int mf_idx, totface = dm->getNumTessFaces(dm), @@ -464,11 +473,11 @@ void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob) int totvert, totedge /*, totface */ /* UNUSED */, totloop, totpoly; int did_shapekeys = 0; - memset(&tmp.vdata, 0, sizeof(tmp.vdata)); - memset(&tmp.edata, 0, sizeof(tmp.edata)); - memset(&tmp.fdata, 0, sizeof(tmp.fdata)); - memset(&tmp.ldata, 0, sizeof(tmp.ldata)); - memset(&tmp.pdata, 0, sizeof(tmp.pdata)); + CustomData_reset(&tmp.vdata); + CustomData_reset(&tmp.edata); + CustomData_reset(&tmp.fdata); + CustomData_reset(&tmp.ldata); + CustomData_reset(&tmp.pdata); totvert = tmp.totvert = dm->getNumVerts(dm); totedge = tmp.totedge = dm->getNumEdges(dm); @@ -625,6 +634,12 @@ void *DM_get_tessface_data(DerivedMesh *dm, int index, int type) return CustomData_get(&dm->faceData, index, type); } +void *DM_get_poly_data(DerivedMesh *dm, int index, int type) +{ + return CustomData_get(&dm->polyData, index, type); +} + + void *DM_get_vert_data_layer(DerivedMesh *dm, int type) { if (type == CD_MVERT) @@ -1373,7 +1388,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos ModifierData *firstmd, *md, *previewmd = NULL; CDMaskLink *datamasks, *curr; /* XXX Always copying POLYINDEX, else tessellated data are no more valid! */ - CustomDataMask mask, nextmask, append_mask = CD_MASK_POLYINDEX; + CustomDataMask mask, nextmask, append_mask = CD_MASK_ORIGINDEX; float (*deformedVerts)[3] = NULL; DerivedMesh *dm = NULL, *orcodm, *clothorcodm, *finaldm; int numVerts = me->totvert; @@ -1801,7 +1816,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos #if 0 if (num_tessface == 0 && finaldm->getNumTessFaces(finaldm) == 0) #else - if (finaldm->getNumTessFaces(finaldm) == 0) /* || !CustomData_has_layer(&finaldm->faceData, CD_POLYINDEX)) */ + if (finaldm->getNumTessFaces(finaldm) == 0) /* || !CustomData_has_layer(&finaldm->faceData, CD_ORIGINDEX)) */ #endif { finaldm->recalcTessellation(finaldm); @@ -1809,8 +1824,8 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos /* Even if tessellation is not needed, some modifiers might have modified CD layers * (like mloopcol or mloopuv), hence we have to update those. */ else if (finaldm->dirty & DM_DIRTY_TESS_CDLAYERS) { - /* A tessellation already exists, it should always have a CD_POLYINDEX. */ - BLI_assert(CustomData_has_layer(&finaldm->faceData, CD_POLYINDEX)); + /* A tessellation already exists, it should always have a CD_ORIGINDEX. */ + BLI_assert(CustomData_has_layer(&finaldm->faceData, CD_ORIGINDEX)); DM_update_tessface_data(finaldm); } /* Need to watch this, it can cause issues, see bug [#29338] */ diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index c6fa2de6545..e1e868b234e 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -485,7 +485,7 @@ static int read_undosave(bContext *C, UndoElem *uel) int success = 0, fileflags; /* This is needed so undoing/redoing doesn't crash with threaded previews going */ - WM_jobs_stop_all(CTX_wm_manager(C)); + WM_jobs_kill_all_except(CTX_wm_manager(C), CTX_wm_screen(C)); BLI_strncpy(mainstr, G.main->name, sizeof(mainstr)); /* temporal store */ diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index 1f02ad1ea5a..2e0b3a3c64a 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -614,14 +614,29 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm, CDDerivedMesh *cddm = (CDDerivedMesh *) dm; MVert *mv = cddm->mvert; MFace *mf = DM_get_tessface_data_layer(dm, CD_MFACE); - MCol *realcol = dm->getTessFaceDataArray(dm, CD_TEXTURE_MCOL); float *nors = dm->getTessFaceDataArray(dm, CD_NORMAL); MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE); - int i, j, orig, *index = DM_get_tessface_data_layer(dm, CD_ORIGINDEX); - int startFace = 0 /*, lastFlag = 0xdeadbeef */ /* UNUSED */; - MCol *mcol = dm->getTessFaceDataArray(dm, CD_PREVIEW_MCOL); - if (!mcol) - mcol = dm->getTessFaceDataArray(dm, CD_MCOL); + MCol *mcol; + int i, orig; + int colType, startFace = 0; + + /* double lookup */ + const int *index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX); + const int *index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX); + if ((index_mf_to_mpoly && index_mp_to_orig) == FALSE) { + index_mf_to_mpoly = index_mp_to_orig = NULL; + } + + colType = CD_TEXTURE_MCOL; + mcol = dm->getTessFaceDataArray(dm, colType); + if (!mcol) { + colType = CD_PREVIEW_MCOL; + mcol = dm->getTessFaceDataArray(dm, colType); + } + if (!mcol) { + colType = CD_MCOL; + mcol = dm->getTessFaceDataArray(dm, colType); + } cdDM_update_normals_from_pbvh(dm); @@ -636,8 +651,8 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm, draw_option = drawParams(tf ? &tf[i] : NULL, (mcol != NULL), mf->mat_nr); } else { - if (index) { - orig = *index++; + if (index_mf_to_mpoly) { + orig = DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, i); if (orig == ORIGINDEX_NONE) { if (nors) nors += 3; continue; } if (drawParamsMapped) { draw_option = drawParamsMapped(userData, orig); } else { if (nors) nors += 3; continue; } @@ -699,42 +714,11 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm, } } else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */ - MCol *col = realcol; - if (!col) - col = mcol; - GPU_vertex_setup(dm); GPU_normal_setup(dm); GPU_uv_setup(dm); - if (col != NULL) { -#if 0 - if (realcol && dm->drawObject->colType == CD_TEXTURE_MCOL) { - col = 0; - } - else if (mcol && dm->drawObject->colType == CD_MCOL) { - col = 0; - } - - if (col != 0) -#endif - { - unsigned char *colors = MEM_mallocN(dm->getNumTessFaces(dm) * 4 * 3 * sizeof(unsigned char), "cdDM_drawFacesTex_common"); - for (i = 0; i < dm->getNumTessFaces(dm); i++) { - for (j = 0; j < 4; j++) { - /* bgr -> rgb is intentional (and stupid), but how its stored internally */ - colors[i * 12 + j * 3] = col[i * 4 + j].b; - colors[i * 12 + j * 3 + 1] = col[i * 4 + j].g; - colors[i * 12 + j * 3 + 2] = col[i * 4 + j].r; - } - } - GPU_color3_upload(dm, colors); - MEM_freeN(colors); - if (realcol) - dm->drawObject->colType = CD_TEXTURE_MCOL; - else if (mcol) - dm->drawObject->colType = CD_MCOL; - } - GPU_color_setup(dm); + if (mcol) { + GPU_color_setup(dm, colType); } if (!GPU_buffer_legacy(dm)) { @@ -755,15 +739,18 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm, draw_option = drawParams(tf ? &tf[actualFace] : NULL, (mcol != NULL), mf[actualFace].mat_nr); } else { - if (index) { - orig = index[actualFace]; - if (orig == ORIGINDEX_NONE) continue; - if (drawParamsMapped) + if (index_mf_to_mpoly) { + orig = DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, actualFace); + if (orig == ORIGINDEX_NONE) { + continue; + } + if (drawParamsMapped) { draw_option = drawParamsMapped(userData, orig); + } } - else - if (drawParamsMapped) + else if (drawParamsMapped) { draw_option = drawParamsMapped(userData, actualFace); + } } /* flush buffer if current triangle isn't drawable or it's last triangle */ @@ -781,7 +768,7 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm, int count = (i - startFace + (draw_option != DM_DRAW_OPTION_SKIP ? 1 : 0)) * 3; if (count) { - if (col) + if (mcol && draw_option != DM_DRAW_OPTION_NO_MCOL) GPU_color_switch(1); else GPU_color_switch(0); @@ -816,16 +803,32 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm, CDDerivedMesh *cddm = (CDDerivedMesh *) dm; MVert *mv = cddm->mvert; MFace *mf = cddm->mface; - MCol *mc; + MCol *mcol; float *nors = DM_get_tessface_data_layer(dm, CD_NORMAL); - int useColors = flag & DM_DRAW_USE_COLORS; - int i, orig, *index = DM_get_tessface_data_layer(dm, CD_ORIGINDEX); + int colType, useColors = flag & DM_DRAW_USE_COLORS; + int i, orig; + + + /* double lookup */ + const int *index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX); + const int *index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX); + if ((index_mf_to_mpoly && index_mp_to_orig) == FALSE) { + index_mf_to_mpoly = index_mp_to_orig = NULL; + } + + + colType = CD_ID_MCOL; + mcol = DM_get_tessface_data_layer(dm, colType); + if (!mcol) { + colType = CD_PREVIEW_MCOL; + mcol = DM_get_tessface_data_layer(dm, colType); + } + if (!mcol) { + colType = CD_MCOL; + mcol = DM_get_tessface_data_layer(dm, colType); + } - mc = DM_get_tessface_data_layer(dm, CD_ID_MCOL); - if (!mc) - mc = DM_get_tessface_data_layer(dm, CD_PREVIEW_MCOL); - if (!mc) - mc = DM_get_tessface_data_layer(dm, CD_MCOL); + printf("%s: %p(%d/%d)\n", __func__, mcol, CD_ID_MCOL, colType); cdDM_update_normals_from_pbvh(dm); @@ -837,7 +840,7 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm, int drawSmooth = (flag & DM_DRAW_ALWAYS_SMOOTH) ? 1 : (mf->flag & ME_SMOOTH); DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL; - orig = (index == NULL) ? i : *index++; + orig = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, i) : i; if (orig == ORIGINDEX_NONE) draw_option = setMaterial(mf->mat_nr + 1, NULL); @@ -847,8 +850,8 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm, if (draw_option != DM_DRAW_OPTION_SKIP) { unsigned char *cp = NULL; - if (useColors && mc) - cp = (unsigned char *)&mc[i * 4]; + if (useColors && mcol) + cp = (unsigned char *)&mcol[i * 4]; /* no need to set shading mode to flat because * normals are already used to change shading */ @@ -908,8 +911,9 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm, int prevstart = 0; GPU_vertex_setup(dm); GPU_normal_setup(dm); - if (useColors && mc) - GPU_color_setup(dm); + if (useColors && mcol) { + GPU_color_setup(dm, colType); + } if (!GPU_buffer_legacy(dm)) { int tottri = dm->drawObject->tot_triangle_point / 3; glShadeModel(GL_SMOOTH); @@ -936,7 +940,7 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm, if (i != tottri - 1) next_actualFace = dm->drawObject->triangle_to_mface[i + 1]; - orig = (index == NULL) ? actualFace : index[actualFace]; + orig = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, actualFace) : actualFace; if (orig == ORIGINDEX_NONE) draw_option = setMaterial(mface->mat_nr + 1, NULL); @@ -1041,7 +1045,14 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, /* MTFace *tf = dm->getTessFaceDataArray(dm, CD_MTFACE); */ /* UNUSED */ float (*nors)[3] = dm->getTessFaceDataArray(dm, CD_NORMAL); int a, b, do_draw, matnr, new_matnr; - int orig, *index = dm->getTessFaceDataArray(dm, CD_ORIGINDEX); + int orig; + + /* double lookup */ + const int *index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX); + const int *index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX); + if ((index_mf_to_mpoly && index_mp_to_orig) == FALSE) { + index_mf_to_mpoly = index_mp_to_orig = NULL; + } cdDM_update_normals_from_pbvh(dm); @@ -1074,7 +1085,7 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, continue; } else if (setDrawOptions) { - orig = (index) ? index[a] : a; + orig = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, a) : a; if (orig == ORIGINDEX_NONE) { /* since the material is set by setMaterial(), faces with no @@ -1335,7 +1346,14 @@ static void cdDM_drawMappedFacesMat(DerivedMesh *dm, MFace *mf = cddm->mface; float (*nors)[3] = dm->getTessFaceDataArray(dm, CD_NORMAL); int a, matnr, new_matnr; - int orig, *index = dm->getTessFaceDataArray(dm, CD_ORIGINDEX); + int orig; + + /* double lookup */ + const int *index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX); + const int *index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX); + if ((index_mf_to_mpoly && index_mp_to_orig) == FALSE) { + index_mf_to_mpoly = index_mp_to_orig = NULL; + } cdDM_update_normals_from_pbvh(dm); @@ -1364,7 +1382,7 @@ static void cdDM_drawMappedFacesMat(DerivedMesh *dm, /* skipping faces */ if (setFace) { - orig = (index) ? index[a] : a; + orig = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, a) : a; if (orig != ORIGINDEX_NONE && !setFace(userData, orig)) continue; @@ -1527,11 +1545,6 @@ void CDDM_recalc_tessellation_ex(DerivedMesh *dm, const int do_face_nor_cpy) dm->numTessFaceData, dm->numLoopData, dm->numPolyData, do_face_nor_cpy); - if (!CustomData_get_layer(&dm->faceData, CD_ORIGINDEX)) { - int *polyIndex = CustomData_get_layer(&dm->faceData, CD_POLYINDEX); - CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_REFERENCE, polyIndex, dm->numTessFaceData); - } - cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE); /* Tessellation recreated faceData, and the active layer indices need to get re-propagated @@ -1643,7 +1656,6 @@ DerivedMesh *CDDM_new(int numVerts, int numEdges, int numTessFaces, int numLoops CustomData_add_layer(&dm->vertData, CD_ORIGINDEX, CD_CALLOC, NULL, numVerts); CustomData_add_layer(&dm->edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges); CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_CALLOC, NULL, numTessFaces); - CustomData_add_layer(&dm->faceData, CD_POLYINDEX, CD_CALLOC, NULL, numTessFaces); CustomData_add_layer(&dm->polyData, CD_ORIGINDEX, CD_CALLOC, NULL, numPolys); CustomData_add_layer(&dm->vertData, CD_MVERT, CD_CALLOC, NULL, numVerts); @@ -1667,7 +1679,6 @@ DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *UNUSED(ob)) DerivedMesh *dm = &cddm->dm; CustomDataMask mask = CD_MASK_MESH & (~CD_MASK_MDISPS); int alloctype; - int *polyindex = NULL; /* this does a referenced copy, with an exception for fluidsim */ @@ -1682,7 +1693,7 @@ DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *UNUSED(ob)) mesh->totvert); CustomData_merge(&mesh->edata, &dm->edgeData, mask, alloctype, mesh->totedge); - CustomData_merge(&mesh->fdata, &dm->faceData, mask | CD_MASK_POLYINDEX, alloctype, + CustomData_merge(&mesh->fdata, &dm->faceData, mask | CD_MASK_ORIGINDEX, alloctype, mesh->totface); CustomData_merge(&mesh->ldata, &dm->loopData, mask, alloctype, mesh->totloop); @@ -1695,17 +1706,12 @@ DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *UNUSED(ob)) cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY); cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE); - /* commented since even when CD_POLYINDEX was first added this line fails + /* commented since even when CD_ORIGINDEX was first added this line fails * on the default cube, (after editmode toggle too) - campbell */ #if 0 - BLI_assert(CustomData_has_layer(&cddm->dm.faceData, CD_POLYINDEX)); + BLI_assert(CustomData_has_layer(&cddm->dm.faceData, CD_ORIGINDEX)); #endif - polyindex = CustomData_get_layer(&dm->faceData, CD_POLYINDEX); - if (!CustomData_has_layer(&cddm->dm.faceData, CD_ORIGINDEX)) { - CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_REFERENCE, polyindex, mesh->totface); - } - return dm; } @@ -1954,7 +1960,6 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps, BM_mesh_elem_index_ensure(bm, BM_FACE); - polyindex = dm->getTessFaceDataArray(dm, CD_POLYINDEX); index = dm->getTessFaceDataArray(dm, CD_ORIGINDEX); for (i = 0; i < dm->numTessFaceData; i++, index++, polyindex++) { MFace *mf = &mface[i]; @@ -1968,8 +1973,8 @@ static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps, mf->mat_nr = efa->mat_nr; mf->flag = BM_face_flag_to_mflag(efa); - *index = add_orig ? BM_elem_index_get(efa) : *(int *)CustomData_bmesh_get(&bm->pdata, efa->head.data, CD_ORIGINDEX); - *polyindex = BM_elem_index_get(efa); + /* map mfaces to polygons in the same cddm intentionally */ + *index = BM_elem_index_get(efa); loops_to_customdata_corners(bm, &dm->faceData, i, l, numCol, numTex); test_index_face(mf, &dm->faceData, i, 3); @@ -2036,6 +2041,7 @@ static DerivedMesh *cddm_copy_ex(DerivedMesh *source, int faces_from_tessfaces) source->getVertDataArray(source, CD_ORIGINDEX); source->getEdgeDataArray(source, CD_ORIGINDEX); source->getTessFaceDataArray(source, CD_ORIGINDEX); + source->getPolyDataArray(source, CD_ORIGINDEX); /* this initializes dm, and copies all non mvert/medge/mface layers */ DM_from_template(dm, source, DM_TYPE_CDDM, numVerts, numEdges, numTessFaces, @@ -2090,6 +2096,7 @@ DerivedMesh *CDDM_from_template(DerivedMesh *source, source->getVertDataArray(source, CD_ORIGINDEX); source->getEdgeDataArray(source, CD_ORIGINDEX); source->getTessFaceDataArray(source, CD_ORIGINDEX); + source->getPolyDataArray(source, CD_ORIGINDEX); /* this does a copy of all non mvert/medge/mface layers */ DM_from_template(dm, source, DM_TYPE_CDDM, numVerts, numEdges, numTessFaces, numLoops, numPolys); @@ -2107,8 +2114,6 @@ DerivedMesh *CDDM_from_template(DerivedMesh *source, CustomData_add_layer(&dm->edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges); if (!CustomData_get_layer(&dm->faceData, CD_ORIGINDEX)) CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_CALLOC, NULL, numTessFaces); - if (!CustomData_get_layer(&dm->faceData, CD_POLYINDEX)) - CustomData_add_layer(&dm->faceData, CD_POLYINDEX, CD_CALLOC, NULL, numTessFaces); cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT); cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE); @@ -2173,8 +2178,8 @@ void CDDM_calc_normals_mapping_ex(DerivedMesh *dm, const short only_face_normals CDDM_recalc_tessellation_ex(dm, FALSE); } else { - /* A tessellation already exists, it should always have a CD_POLYINDEX */ - BLI_assert(CustomData_has_layer(&dm->faceData, CD_POLYINDEX)); + /* A tessellation already exists, it should always have a CD_ORIGINDEX */ + BLI_assert(CustomData_has_layer(&dm->faceData, CD_ORIGINDEX)); CustomData_free_layers(&dm->faceData, CD_NORMAL, dm->numTessFaceData); } @@ -2184,7 +2189,7 @@ void CDDM_calc_normals_mapping_ex(DerivedMesh *dm, const short only_face_normals /* calculate face normals */ BKE_mesh_calc_normals_mapping_ex(cddm->mvert, dm->numVertData, CDDM_get_loops(dm), CDDM_get_polys(dm), dm->numLoopData, dm->numPolyData, NULL, cddm->mface, dm->numTessFaceData, - CustomData_get_layer(&dm->faceData, CD_POLYINDEX), face_nors, + CustomData_get_layer(&dm->faceData, CD_ORIGINDEX), face_nors, only_face_normals); CustomData_add_layer(&dm->faceData, CD_NORMAL, CD_ASSIGN, @@ -2458,7 +2463,7 @@ void CDDM_calc_edges_tessface(DerivedMesh *dm) numEdges = BLI_edgehash_size(eh); /* write new edges into a temporary CustomData */ - memset(&edgeData, 0, sizeof(edgeData)); + CustomData_reset(&edgeData); CustomData_add_layer(&edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges); CustomData_add_layer(&edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges); @@ -2523,7 +2528,7 @@ void CDDM_calc_edges(DerivedMesh *dm) numEdges = BLI_edgehash_size(eh); /* write new edges into a temporary CustomData */ - memset(&edgeData, 0, sizeof(edgeData)); + CustomData_reset(&edgeData); CustomData_add_layer(&edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges); CustomData_add_layer(&edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges); diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c index 0c369a463d5..75276adf518 100644 --- a/source/blender/blenkernel/intern/colortools.c +++ b/source/blender/blenkernel/intern/colortools.c @@ -182,14 +182,14 @@ void curvemapping_set_black_white(CurveMapping *cumap, const float black[3], con /* ********** NOTE: requires curvemapping_changed() call after ******** */ /* remove specified point */ -void curvemap_remove_point(CurveMap *cuma, CurveMapPoint *point) +int curvemap_remove_point(CurveMap *cuma, CurveMapPoint *point) { CurveMapPoint *cmp; int a, b, removed = 0; /* must have 2 points minimum */ if (cuma->totpoint <= 2) - return; + return FALSE; cmp = MEM_mallocN((cuma->totpoint) * sizeof(CurveMapPoint), "curve points"); @@ -205,6 +205,7 @@ void curvemap_remove_point(CurveMap *cuma, CurveMapPoint *point) MEM_freeN(cuma->curve); cuma->curve = cmp; cuma->totpoint -= removed; + return (removed != 0); } /* removes with flag set */ diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index 06dad495d81..67aaaceaa38 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -820,8 +820,8 @@ static void basisNurb(float t, short order, short pnts, float *knots, float *bas /* this is for float inaccuracy */ if (t < knots[0]) t = knots[0]; - else - if (t > knots[opp2]) t = knots[opp2]; + else if (t > knots[opp2]) + t = knots[opp2]; /* this part is order '1' */ o2 = order + 1; diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index d8082902a44..93c776ae30e 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -74,8 +74,11 @@ BLI_STATIC_ASSERT(sizeof(((CustomData *)NULL)->typemap) / /********************* Layer type information **********************/ typedef struct LayerTypeInfo { int size; /* the memory size of one element of this layer's data */ - const char *structname; /* name of the struct used, for file writing */ - int structnum; /* number of structs per element, for file writing */ + + /** name of the struct used, for file writing */ + const char *structname; + /** number of structs per element, for file writing */ + int structnum; /** * default layer name. @@ -1061,8 +1064,8 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = { /* 8: CD_NORMAL */ /* 3 floats per normal vector */ {sizeof(float) * 3, "vec3f", 1, NULL, NULL, NULL, NULL, NULL, NULL}, - /* 9: CD_POLYINDEX */ - {sizeof(int), "MIntProperty", 1, NULL, NULL, NULL, NULL, NULL, NULL}, + /* 9: CD_POLYINDEX (deprecated) */ + {sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL, NULL}, /* 10: CD_PROP_FLT */ {sizeof(MFloatProperty), "MFloatProperty", 1, "Float", layerCopy_propFloat, NULL, NULL, NULL}, /* 11: CD_PROP_INT */ @@ -1180,7 +1183,7 @@ const CustomDataMask CD_MASK_DERIVEDMESH = CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_MTEXPOLY | CD_MASK_PREVIEW_MLOOPCOL | CD_MASK_PROP_STR | CD_MASK_ORIGSPACE | CD_MASK_ORIGSPACE_MLOOP | CD_MASK_ORCO | CD_MASK_TANGENT | CD_MASK_PREVIEW_MCOL | CD_MASK_NORMAL | CD_MASK_SHAPEKEY | CD_MASK_RECAST | - CD_MASK_ORIGINDEX | CD_MASK_POLYINDEX | CD_MASK_MVERT_SKIN; + CD_MASK_ORIGINDEX | CD_MASK_MVERT_SKIN; const CustomDataMask CD_MASK_BMESH = CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_MTEXPOLY | CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | @@ -1239,6 +1242,13 @@ void CustomData_update_typemap(CustomData *data) } } +static int customdata_typemap_is_valid(const CustomData *data) +{ + CustomData data_copy = *data; + CustomData_update_typemap(&data_copy); + return (memcmp(data->typemap, data_copy.typemap, sizeof(data->typemap)) == 0); +} + void CustomData_merge(const struct CustomData *source, struct CustomData *dest, CustomDataMask mask, int alloctype, int totelem) { @@ -1304,7 +1314,7 @@ void CustomData_merge(const struct CustomData *source, struct CustomData *dest, void CustomData_copy(const struct CustomData *source, struct CustomData *dest, CustomDataMask mask, int alloctype, int totelem) { - memset(dest, 0, sizeof(*dest)); + CustomData_reset(dest); if (source->external) dest->external = MEM_dupallocN(source->external); @@ -1335,6 +1345,12 @@ static void CustomData_external_free(CustomData *data) } } +void CustomData_reset(CustomData *data) +{ + memset(data, 0, sizeof(*data)); + fill_vn_i(data->typemap, CD_NUMTYPES, -1); +} + void CustomData_free(CustomData *data, int totelem) { int i; @@ -1346,8 +1362,7 @@ void CustomData_free(CustomData *data, int totelem) MEM_freeN(data->layers); CustomData_external_free(data); - - memset(data, 0, sizeof(*data)); + CustomData_reset(data); } static void customData_update_offsets(CustomData *data) @@ -1366,9 +1381,10 @@ static void customData_update_offsets(CustomData *data) CustomData_update_typemap(data); } -int CustomData_get_layer_index(const CustomData *data, int type) +/* to use when we're in the middle of modifying layers */ +static int CustomData_get_layer_index__notypemap(const CustomData *data, int type) { - int i; + int i; for (i = 0; i < data->totlayer; ++i) if (data->layers[i].type == type) @@ -1377,11 +1393,21 @@ int CustomData_get_layer_index(const CustomData *data, int type) return -1; } +/* -------------------------------------------------------------------- */ +/* index values to access the layers (offset from the layer start) */ + +int CustomData_get_layer_index(const CustomData *data, int type) +{ + BLI_assert(customdata_typemap_is_valid(data)); + return data->typemap[type]; +} + int CustomData_get_layer_index_n(const struct CustomData *data, int type, int n) { int i = CustomData_get_layer_index(data, type); if (i != -1) { + BLI_assert(i + n < data->totlayer); i = (data->layers[i + n].type == type) ? (i + n) : (-1); } @@ -1401,91 +1427,62 @@ int CustomData_get_named_layer_index(const CustomData *data, int type, const cha int CustomData_get_active_layer_index(const CustomData *data, int type) { - if (!data->totlayer) - return -1; - - if (data->typemap[type] != -1) { - return data->typemap[type] + data->layers[data->typemap[type]].active; - } - - return -1; + const int layer_index = data->typemap[type]; + BLI_assert(customdata_typemap_is_valid(data)); + return (layer_index != -1) ? layer_index + data->layers[layer_index].active: -1; } int CustomData_get_render_layer_index(const CustomData *data, int type) { - int i; - - for (i = 0; i < data->totlayer; ++i) - if (data->layers[i].type == type) - return i + data->layers[i].active_rnd; - - return -1; + const int layer_index = data->typemap[type]; + BLI_assert(customdata_typemap_is_valid(data)); + return (layer_index != -1) ? layer_index + data->layers[layer_index].active_rnd : -1; } int CustomData_get_clone_layer_index(const CustomData *data, int type) { - int i; - - for (i = 0; i < data->totlayer; ++i) - if (data->layers[i].type == type) - return i + data->layers[i].active_clone; - - return -1; + const int layer_index = data->typemap[type]; + BLI_assert(customdata_typemap_is_valid(data)); + return (layer_index != -1) ? layer_index + data->layers[layer_index].active_clone : -1; } int CustomData_get_stencil_layer_index(const CustomData *data, int type) { - int i; + const int layer_index = data->typemap[type]; + BLI_assert(customdata_typemap_is_valid(data)); + return (layer_index != -1) ? layer_index + data->layers[layer_index].active_mask : -1; +} - for (i = 0; i < data->totlayer; ++i) - if (data->layers[i].type == type) - return i + data->layers[i].active_mask; - return -1; -} +/* -------------------------------------------------------------------- */ +/* index values per layer type */ int CustomData_get_active_layer(const CustomData *data, int type) { - int i; - - for (i = 0; i < data->totlayer; ++i) - if (data->layers[i].type == type) - return data->layers[i].active; - - return -1; + const int layer_index = data->typemap[type]; + BLI_assert(customdata_typemap_is_valid(data)); + return (layer_index != -1) ? data->layers[layer_index].active : -1; } int CustomData_get_render_layer(const CustomData *data, int type) { - int i; - - for (i = 0; i < data->totlayer; ++i) - if (data->layers[i].type == type) - return data->layers[i].active_rnd; - - return -1; + const int layer_index = data->typemap[type]; + BLI_assert(customdata_typemap_is_valid(data)); + return (layer_index != -1) ? data->layers[layer_index].active_rnd : -1; } int CustomData_get_clone_layer(const CustomData *data, int type) { - int i; - - for (i = 0; i < data->totlayer; ++i) - if (data->layers[i].type == type) - return data->layers[i].active_clone; - - return -1; + const int layer_index = data->typemap[type]; + BLI_assert(customdata_typemap_is_valid(data)); + return (layer_index != -1) ? data->layers[layer_index].active_clone : -1; } int CustomData_get_stencil_layer(const CustomData *data, int type) { - int i; - - for (i = 0; i < data->totlayer; ++i) - if (data->layers[i].type == type) - return data->layers[i].active_mask; - - return -1; + const int layer_index = data->typemap[type]; + BLI_assert(customdata_typemap_is_valid(data)); + return (layer_index != -1) ? data->layers[layer_index].active_mask : -1; } void CustomData_set_layer_active(CustomData *data, int type, int n) @@ -1716,7 +1713,7 @@ int CustomData_free_layer(CustomData *data, int type, int totelem, int index) /* if layer was last of type in array, set new active layer */ if ((index >= data->totlayer) || (data->layers[index].type != type)) { - i = CustomData_get_layer_index(data, type); + i = CustomData_get_layer_index__notypemap(data, type); if (i >= 0) for (; i < data->totlayer && data->layers[i].type == type; i++) { @@ -1731,7 +1728,6 @@ int CustomData_free_layer(CustomData *data, int type, int totelem, int index) customData_resize(data, -CUSTOMDATA_GROW); customData_update_offsets(data); - CustomData_update_typemap(data); return 1; } diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c index 82938ed1d39..7c13ca388e0 100644 --- a/source/blender/blenkernel/intern/deform.c +++ b/source/blender/blenkernel/intern/deform.c @@ -790,3 +790,23 @@ void defvert_clear(MDeformVert *dvert) dvert->totweight = 0; } + +/** + * \return The first group index shared by both deform verts + * or -1 if none are found. + */ +int defvert_find_shared(const MDeformVert *dvert_a, const MDeformVert *dvert_b) +{ + if (dvert_a->totweight && dvert_b->totweight) { + MDeformWeight *dw = dvert_a->dw; + unsigned int i; + + for (i = dvert_a->totweight; i != 0; i--, dw++) { + if (dw->weight > 0.0f && defvert_find_weight(dvert_b, dw->def_nr) > 0.0f) { + return dw->def_nr; + } + } + } + + return -1; +} diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c index 8ceaab56f83..5dd0f08dc71 100644 --- a/source/blender/blenkernel/intern/idprop.c +++ b/source/blender/blenkernel/intern/idprop.c @@ -492,6 +492,30 @@ void IDP_ReplaceInGroup(IDProperty *group, IDProperty *prop) } } +/* + * If a property is missing in \a dest, add it. + */ +void IDP_MergeGroup(IDProperty *dest, IDProperty *src, const int do_overwrite) +{ + IDProperty *prop; + + if (do_overwrite) { + for (prop = src->data.group.first; prop; prop = prop->next) { + IDProperty *copy = IDP_CopyProperty(prop); + IDP_ReplaceInGroup(dest, copy); + } + } + else { + for (prop = src->data.group.first; prop; prop = prop->next) { + if (IDP_GetPropertyFromGroup(dest, prop->name) == NULL) { + IDProperty *copy = IDP_CopyProperty(prop); + dest->len++; + BLI_addtail(&dest->data.group, copy); + } + } + } +} + /* returns 0 if an id property with the same name exists and it failed, * or 1 if it succeeded in adding to the group.*/ int IDP_AddToGroup(IDProperty *group, IDProperty *prop) @@ -608,60 +632,77 @@ IDProperty *IDP_GetProperties(ID *id, int create_if_needed) } } -int IDP_EqualsProperties(IDProperty *prop1, IDProperty *prop2) +/** + * \param is_strict When FALSE treat missing items as a match */ +int IDP_EqualsProperties_ex(IDProperty *prop1, IDProperty *prop2, const int is_strict) { if (prop1 == NULL && prop2 == NULL) return 1; else if (prop1 == NULL || prop2 == NULL) - return 0; + return is_strict ? 0 : 1; else if (prop1->type != prop2->type) return 0; - if (prop1->type == IDP_INT) - return (IDP_Int(prop1) == IDP_Int(prop2)); - else if (prop1->type == IDP_FLOAT) - return (IDP_Float(prop1) == IDP_Float(prop2)); - else if (prop1->type == IDP_DOUBLE) - return (IDP_Double(prop1) == IDP_Double(prop2)); - else if (prop1->type == IDP_STRING) - return ((prop1->len == prop2->len) && strncmp(IDP_String(prop1), IDP_String(prop2), prop1->len) == 0); - else if (prop1->type == IDP_ARRAY) { - if (prop1->len == prop2->len && prop1->subtype == prop2->subtype) - return memcmp(IDP_Array(prop1), IDP_Array(prop2), idp_size_table[(int)prop1->subtype] * prop1->len); - else - return 0; - } - else if (prop1->type == IDP_GROUP) { - IDProperty *link1, *link2; - - if (BLI_countlist(&prop1->data.group) != BLI_countlist(&prop2->data.group)) - return 0; - - for (link1 = prop1->data.group.first; link1; link1 = link1->next) { - link2 = IDP_GetPropertyFromGroup(prop2, link1->name); - - if (!IDP_EqualsProperties(link1, link2)) + switch (prop1->type) { + case IDP_INT: + return (IDP_Int(prop1) == IDP_Int(prop2)); + case IDP_FLOAT: + return (IDP_Float(prop1) == IDP_Float(prop2)); + case IDP_DOUBLE: + return (IDP_Double(prop1) == IDP_Double(prop2)); + case IDP_STRING: + return ((prop1->len == prop2->len) && strncmp(IDP_String(prop1), IDP_String(prop2), prop1->len) == 0); + case IDP_ARRAY: + if (prop1->len == prop2->len && prop1->subtype == prop2->subtype) { + return memcmp(IDP_Array(prop1), IDP_Array(prop2), idp_size_table[(int)prop1->subtype] * prop1->len); + } + else { return 0; - } + } + case IDP_GROUP: + { + IDProperty *link1, *link2; - return 1; - } - else if (prop1->type == IDP_IDPARRAY) { - IDProperty *array1 = IDP_IDPArray(prop1); - IDProperty *array2 = IDP_IDPArray(prop2); - int i; + if (is_strict && BLI_countlist(&prop1->data.group) != BLI_countlist(&prop2->data.group)) + return 0; - if (prop1->len != prop2->len) - return 0; - - for (i = 0; i < prop1->len; i++) - if (!IDP_EqualsProperties(&array1[i], &array2[i])) + for (link1 = prop1->data.group.first; link1; link1 = link1->next) { + link2 = IDP_GetPropertyFromGroup(prop2, link1->name); + + if (!IDP_EqualsProperties_ex(link1, link2, is_strict)) + return 0; + } + + return 1; + } + case IDP_IDPARRAY: + { + IDProperty *array1 = IDP_IDPArray(prop1); + IDProperty *array2 = IDP_IDPArray(prop2); + int i; + + if (prop1->len != prop2->len) return 0; + + for (i = 0; i < prop1->len; i++) + if (!IDP_EqualsProperties(&array1[i], &array2[i])) + return 0; + return 1; + } + default: + /* should never get here */ + BLI_assert(0); + break; } - + return 1; } +int IDP_EqualsProperties(IDProperty *prop1, IDProperty *prop2) +{ + return IDP_EqualsProperties_ex(prop1, prop2, TRUE); +} + /* 'val' is never NULL, don't check */ IDProperty *IDP_New(const int type, const IDPropertyTemplate *val, const char *name) { diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index 39dcd73e0e5..2de5425a04d 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -1513,7 +1513,7 @@ static void hair_velocity_smoothing(ClothModifierData *clmd, lfVector *lF, lfVec i = HAIR_GRID_INDEX(lX[v], gmin, gmax, 0); j = HAIR_GRID_INDEX(lX[v], gmin, gmax, 1); k = HAIR_GRID_INDEX(lX[v], gmin, gmax, 2); - if (i < 0 || j < 0 || k < 0 || i > 10 || j >= 10 || k >= 10) + if (i < 0 || j < 0 || k < 0 || i >= 10 || j >= 10 || k >= 10) continue; lF[v][0] += smoothfac * (grid[i][j][k].velocity[0] - lV[v][0]); diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index da0fb895ec2..b7f4c4bd61e 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -378,8 +378,8 @@ float BKE_mask_spline_project_co(MaskSpline *spline, MaskSplinePoint *point, if (len_squared_v2(v1) > proj_eps_squared) { ang1 = angle_v2v2(v1, n1); - if (ang1 > M_PI / 2.0f) - ang1 = M_PI - ang1; + if (ang1 > (float)M_PI / 2.0f) + ang1 = (float)M_PI - ang1; if (ang < 0.0f || ang1 < ang) { ang = ang1; @@ -405,8 +405,8 @@ float BKE_mask_spline_project_co(MaskSpline *spline, MaskSplinePoint *point, if (len_squared_v2(v2) > proj_eps_squared) { ang2 = angle_v2v2(v2, n2); - if (ang2 > M_PI / 2.0f) - ang2 = M_PI - ang2; + if (ang2 > (float)M_PI / 2.0f) + ang2 = (float)M_PI - ang2; if (ang2 < ang) { ang = ang2; @@ -555,7 +555,7 @@ float BKE_mask_point_weight_scalar(MaskSpline *spline, MaskSplinePoint *point, c if (!bezt_next) { return bezt->weight; } - else if (u <= 0.0) { + else if (u <= 0.0f) { return bezt->weight; } else if (u >= 1.0f) { @@ -576,7 +576,7 @@ float BKE_mask_point_weight(MaskSpline *spline, MaskSplinePoint *point, const fl if (!bezt_next) { return bezt->weight; } - else if (u <= 0.0) { + else if (u <= 0.0f) { return bezt->weight; } else if (u >= 1.0f) { @@ -1805,7 +1805,7 @@ static void interp_weights_uv_v2_calc(float r_uv[2], const float pt[2], const fl float pt_on_line[2]; r_uv[0] = closest_to_line_v2(pt_on_line, pt, pt_a, pt_b); r_uv[1] = (len_v2v2(pt_on_line, pt) / len_v2v2(pt_a, pt_b)) * - ((line_point_side_v2(pt_a, pt_b, pt) < 0.0f) ? -1.0 : 1.0); /* this line only sets the sign */ + ((line_point_side_v2(pt_a, pt_b, pt) < 0.0f) ? -1.0f : 1.0f); /* this line only sets the sign */ } diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c index 3561d5db9c0..88393fab79c 100644 --- a/source/blender/blenkernel/intern/mask_rasterize.c +++ b/source/blender/blenkernel/intern/mask_rasterize.c @@ -104,7 +104,7 @@ /* for debugging add... */ #ifndef NDEBUG -/* printf("%u %u %u %u\n", _t[0], _t[1], _t[2], _t[3]); \ */ +/* printf("%u %u %u %u\n", _t[0], _t[1], _t[2], _t[3]); \ */ # define FACE_ASSERT(face, vert_max) \ { \ unsigned int *_t = face; \ @@ -428,7 +428,7 @@ static void layer_bucket_init(MaskRasterLayer *layer, const float pixel_size) /* width and height of each bucket */ const float bucket_size_x = (bucket_dim_x + FLT_EPSILON) / layer->buckets_x; const float bucket_size_y = (bucket_dim_y + FLT_EPSILON) / layer->buckets_y; - const float bucket_max_rad = (max_ff(bucket_size_x, bucket_size_y) * M_SQRT2) + FLT_EPSILON; + const float bucket_max_rad = (max_ff(bucket_size_x, bucket_size_y) * (float)M_SQRT2) + FLT_EPSILON; const float bucket_max_rad_squared = bucket_max_rad * bucket_max_rad; unsigned int *face = &layer->face_array[0][0]; diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c index 592101fbd31..805e77cf84f 100644 --- a/source/blender/blenkernel/intern/mball.c +++ b/source/blender/blenkernel/intern/mball.c @@ -1319,12 +1319,16 @@ static void addtovertices(VERTICES *vertices, VERTEX v) static void vnormal(const float point[3], PROCESS *p, float r_no[3]) { - float delta = 0.2f * p->delta; - float f = p->function(point[0], point[1], point[2]); + const float delta = 0.2f * p->delta; + const float f = p->function(point[0], point[1], point[2]); r_no[0] = p->function(point[0] + delta, point[1], point[2]) - f; r_no[1] = p->function(point[0], point[1] + delta, point[2]) - f; r_no[2] = p->function(point[0], point[1], point[2] + delta) - f; + +#if 1 + normalize_v3(r_no); +#else f = normalize_v3(r_no); if (0) { @@ -1343,6 +1347,7 @@ static void vnormal(const float point[3], PROCESS *p, float r_no[3]) normalize_v3(r_no); } } +#endif } @@ -1500,7 +1505,7 @@ static void find_first_points(PROCESS *mbproc, MetaBall *mb, int a) float f = 0.0f; ml = G_mb.mainb[a]; - f = 1.0 - (mb->thresh / ml->s); + f = 1.0f - (mb->thresh / ml->s); /* Skip, when Stiffness of MetaElement is too small ... MetaElement can't be * visible alone ... but still can influence others MetaElements :-) */ diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index 26120b771bf..6d44473583f 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -469,15 +469,17 @@ void free_dverts(MDeformVert *dvert, int totvert) static void mesh_tessface_clear_intern(Mesh *mesh, int free_customdata) { - if (free_customdata) + if (free_customdata) { CustomData_free(&mesh->fdata, mesh->totface); + } + else { + CustomData_reset(&mesh->fdata); + } mesh->mface = NULL; mesh->mtface = NULL; mesh->mcol = NULL; mesh->totface = 0; - - memset(&mesh->fdata, 0, sizeof(mesh->fdata)); } Mesh *BKE_mesh_add(const char *name) @@ -491,7 +493,13 @@ Mesh *BKE_mesh_add(const char *name) me->texflag = ME_AUTOSPACE; me->flag = ME_TWOSIDED; me->drawflag = ME_DRAWEDGES | ME_DRAWFACES | ME_DRAWCREASES; - + + CustomData_reset(&me->vdata); + CustomData_reset(&me->edata); + CustomData_reset(&me->fdata); + CustomData_reset(&me->pdata); + CustomData_reset(&me->ldata); + return me; } @@ -2125,8 +2133,6 @@ void BKE_mesh_convert_mfaces_to_mpolys_ex(ID *id, CustomData *fdata, CustomData /* just in case some of these layers are filled in (can happen with python created meshes) */ CustomData_free(ldata, totloop_i); CustomData_free(pdata, totpoly_i); - memset(ldata, 0, sizeof(*ldata)); - memset(pdata, 0, sizeof(*pdata)); totpoly = totface_i; mpoly = MEM_callocN(sizeof(MPoly) * totpoly, "mpoly converted"); @@ -2163,7 +2169,7 @@ void BKE_mesh_convert_mfaces_to_mpolys_ex(ID *id, CustomData *fdata, CustomData me->flag &= ~ME_FGON; } - polyindex = CustomData_get_layer(fdata, CD_POLYINDEX); + polyindex = CustomData_get_layer(fdata, CD_ORIGINDEX); j = 0; /* current loop index */ ml = mloop; @@ -2505,12 +2511,9 @@ int BKE_mesh_recalc_tessellation(CustomData *fdata, ScanFillContext sf_ctx; ScanFillVert *sf_vert, *sf_vert_last, *sf_vert_first; ScanFillFace *sf_tri; - int *mface_orig_index = NULL; - BLI_array_declare(mface_orig_index); int *mface_to_poly_map = NULL; BLI_array_declare(mface_to_poly_map); int lindex[4]; /* only ever use 3 in this case */ - int *poly_orig_index; int poly_index, j, mface_index; const int numTex = CustomData_number_of_layers(pdata, CD_MTEXPOLY); @@ -2528,7 +2531,6 @@ int BKE_mesh_recalc_tessellation(CustomData *fdata, mface_index = 0; mp = mpoly; - poly_orig_index = CustomData_get_layer(pdata, CD_ORIGINDEX); for (poly_index = 0; poly_index < totpoly; poly_index++, mp++) { if (mp->totloop < 3) { /* do nothing */ @@ -2548,10 +2550,6 @@ int BKE_mesh_recalc_tessellation(CustomData *fdata, mf->v4 = 0; \ mf->mat_nr = mp->mat_nr; \ mf->flag = mp->flag; \ - if (poly_orig_index) { \ - BLI_array_append(mface_orig_index, \ - poly_orig_index[poly_index]); \ - } \ (void)0 /* ALMOST IDENTICAL TO DEFINE ABOVE (see EXCEPTION) */ @@ -2567,10 +2565,6 @@ int BKE_mesh_recalc_tessellation(CustomData *fdata, mf->v4 = mp->loopstart + 3; /* EXCEPTION */ \ mf->mat_nr = mp->mat_nr; \ mf->flag = mp->flag; \ - if (poly_orig_index) { \ - BLI_array_append(mface_orig_index, \ - poly_orig_index[poly_index]); \ - } \ mf->edcode |= TESSFACE_IS_QUAD; /* EXCEPTION */ \ (void)0 @@ -2617,9 +2611,6 @@ int BKE_mesh_recalc_tessellation(CustomData *fdata, if (totfilltri) { BLI_array_grow_items(mface_to_poly_map, totfilltri); BLI_array_grow_items(mface, totfilltri); - if (poly_orig_index) { - BLI_array_grow_items(mface_orig_index, totfilltri); - } for (sf_tri = sf_ctx.fillfacebase.first; sf_tri; sf_tri = sf_tri->next, mf++) { mface_to_poly_map[mface_index] = poly_index; @@ -2638,10 +2629,6 @@ int BKE_mesh_recalc_tessellation(CustomData *fdata, mf->edcode |= TESSFACE_SCANFILL; /* tag for sorting loop indices */ #endif - if (poly_orig_index) { - mface_orig_index[mface_index] = poly_orig_index[poly_index]; - } - mface_index++; } } @@ -2651,7 +2638,6 @@ int BKE_mesh_recalc_tessellation(CustomData *fdata, } CustomData_free(fdata, totface); - memset(fdata, 0, sizeof(CustomData)); totface = mface_index; @@ -2659,23 +2645,13 @@ int BKE_mesh_recalc_tessellation(CustomData *fdata, if (LIKELY((MEM_allocN_len(mface) / sizeof(*mface)) != totface)) { mface = MEM_reallocN(mface, sizeof(*mface) * totface); mface_to_poly_map = MEM_reallocN(mface_to_poly_map, sizeof(*mface_to_poly_map) * totface); - if (mface_orig_index) { - mface_orig_index = MEM_reallocN(mface_orig_index, sizeof(*mface_orig_index) * totface); - } } CustomData_add_layer(fdata, CD_MFACE, CD_ASSIGN, mface, totface); - /* CD_POLYINDEX will contain an array of indices from tessfaces to the polygons + /* CD_ORIGINDEX will contain an array of indices from tessfaces to the polygons * they are directly tessellated from */ - CustomData_add_layer(fdata, CD_POLYINDEX, CD_ASSIGN, mface_to_poly_map, totface); - if (mface_orig_index) { - /* If polys had a CD_ORIGINDEX layer, then the tessellated faces will get this - * layer as well, pointing to polys from the original mesh (not the polys - * that just got tessellated) */ - CustomData_add_layer(fdata, CD_ORIGINDEX, CD_ASSIGN, mface_orig_index, totface); - } - + CustomData_add_layer(fdata, CD_ORIGINDEX, CD_ASSIGN, mface_to_poly_map, totface); CustomData_from_bmeshpoly(fdata, pdata, ldata, totface); if (do_face_nor_cpy) { @@ -2806,7 +2782,6 @@ int BKE_mesh_mpoly_to_mface(struct CustomData *fdata, struct CustomData *ldata, } CustomData_free(fdata, totface); - memset(fdata, 0, sizeof(CustomData)); totface = k; diff --git a/source/blender/blenkernel/intern/mesh_validate.c b/source/blender/blenkernel/intern/mesh_validate.c index c4d663e17bd..128b9ae242e 100644 --- a/source/blender/blenkernel/intern/mesh_validate.c +++ b/source/blender/blenkernel/intern/mesh_validate.c @@ -944,7 +944,7 @@ void BKE_mesh_calc_edges(Mesh *mesh, int update) totedge = BLI_edgehash_size(eh); /* write new edges into a temporary CustomData */ - memset(&edata, 0, sizeof(edata)); + CustomData_reset(&edata); CustomData_add_layer(&edata, CD_MEDGE, CD_CALLOC, NULL, totedge); med = CustomData_get_layer(&edata, CD_MEDGE); diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c index d34bb99ab98..66f2ff12258 100644 --- a/source/blender/blenkernel/intern/multires.c +++ b/source/blender/blenkernel/intern/multires.c @@ -2085,8 +2085,8 @@ void multires_load_old(Object *ob, Mesh *me) CustomData_add_layer(&me->vdata, l->type, CD_REFERENCE, l->data, me->totvert); for (i = 0, l = me->mr->fdata.layers; i < me->mr->fdata.totlayer; ++i, ++l) CustomData_add_layer(&me->fdata, l->type, CD_REFERENCE, l->data, me->totface); - memset(&me->mr->vdata, 0, sizeof(CustomData)); - memset(&me->mr->fdata, 0, sizeof(CustomData)); + CustomData_reset(&me->mr->vdata); + CustomData_reset(&me->mr->fdata); multires_load_old_vcols(me); multires_load_old_face_flags(me); diff --git a/source/blender/blenkernel/intern/navmesh_conversion.c b/source/blender/blenkernel/intern/navmesh_conversion.c index 5fe4f8e90ba..3bf5f863557 100644 --- a/source/blender/blenkernel/intern/navmesh_conversion.c +++ b/source/blender/blenkernel/intern/navmesh_conversion.c @@ -36,12 +36,12 @@ #include "DNA_meshdata_types.h" -#include "BKE_navmesh_conversion.h" -#include "BKE_cdderivedmesh.h" - #include "BLI_utildefines.h" #include "BLI_math.h" +#include "BKE_navmesh_conversion.h" +#include "BKE_cdderivedmesh.h" + #include "recast-capi.h" BLI_INLINE float area2(const float *a, const float *b, const float *c) diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 3112e8dc13d..cbe3b7dd231 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -1580,11 +1580,11 @@ int BKE_node_clipboard_validate(void) /* lists must be aligned */ BLI_assert(BLI_countlist(&node_clipboard.nodes) == - BLI_countlist(&node_clipboard.nodes_extra_info)); + BLI_countlist(&node_clipboard.nodes_extra_info)); for (node = node_clipboard.nodes.first, node_info = node_clipboard.nodes_extra_info.first; - node; - node = node->next, node_info = node_info->next) + node; + node = node->next, node_info = node_info->next) { /* validate the node against the stored node info */ @@ -2288,6 +2288,7 @@ static void registerShaderNodes(bNodeTreeType *ttype) register_node_type_sh_tex_coord(ttype); register_node_type_sh_particle_info(ttype); register_node_type_sh_bump(ttype); + register_node_type_sh_script(ttype); register_node_type_sh_background(ttype); register_node_type_sh_bsdf_anisotropic(ttype); diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 549d4e2d126..53540001497 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -306,7 +306,7 @@ void BKE_object_free(Object *ob) if (ob->data) { ID *id = ob->data; id->us--; - if (id->us == 0 && id->lib==NULL) { + if (id->us == 0 && id->lib == NULL) { switch (ob->type) { case OB_MESH: BKE_mesh_unlink((Mesh *)id); @@ -864,7 +864,9 @@ Object *BKE_object_add_only_object(int type, const char *name) ob->step_height = 0.15f; ob->jump_speed = 10.0f; ob->fall_speed = 55.0f; - + ob->col_group = 0x01; + ob->col_mask = 0xff; + /* NT fluid sim defaults */ ob->fluidsimSettings = NULL; diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c index 5a302cba2ab..36f96045ced 100644 --- a/source/blender/blenkernel/intern/paint.c +++ b/source/blender/blenkernel/intern/paint.c @@ -36,6 +36,7 @@ #include "DNA_meshdata_types.h" #include "DNA_scene_types.h" #include "DNA_brush_types.h" +#include "DNA_space_types.h" #include "BLI_bitmap.h" #include "BLI_utildefines.h" @@ -87,6 +88,7 @@ Paint *paint_get_active(Scene *sce) Paint *paint_get_active_from_context(const bContext *C) { Scene *sce = CTX_data_scene(C); + SpaceImage *sima; if (sce) { ToolSettings *ts = sce->toolsettings; @@ -95,12 +97,12 @@ Paint *paint_get_active_from_context(const bContext *C) if (sce->basact && sce->basact->object) obact = sce->basact->object; - if (CTX_wm_space_image(C) != NULL) { + if ((sima = CTX_wm_space_image(C)) != NULL) { if (obact && obact->mode == OB_MODE_EDIT) { - if (ts->use_uv_sculpt) - return &ts->uvsculpt->paint; - else + if (sima->mode == SI_MODE_PAINT) return &ts->imapaint.paint; + else if (ts->use_uv_sculpt) + return &ts->uvsculpt->paint; } else { return &ts->imapaint.paint; diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 9e37cc95b8c..d645204d29c 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -618,7 +618,10 @@ typedef struct ParticleRenderData { int do_simplify; int timeoffset; ParticleRenderElem *elems; - int *origindex; + + /* ORIGINDEX */ + const int *index_mf_to_mpoly; + const int *index_mp_to_orig; } ParticleRenderData; static float psys_render_viewport_falloff(double rate, float dist, float width) @@ -791,9 +794,13 @@ int psys_render_simplify_distribution(ParticleThreadContext *ctx, int tot) float *facearea, (*facecenter)[3], size[3], fac, powrate, scaleclamp; float co1[3], co2[3], co3[3], co4[3], lambda, arearatio, t, area, viewport; double vprate; - int *origindex, *facetotvert; + int *facetotvert; int a, b, totorigface, totface, newtot, skipped; + /* double lookup */ + const int *index_mf_to_mpoly; + const int *index_mp_to_orig; + if (part->ren_as != PART_DRAW_PATH || !(part->draw & PART_DRAW_REN_STRAND)) return tot; if (!ctx->sim.psys->renderdata) @@ -807,13 +814,18 @@ int psys_render_simplify_distribution(ParticleThreadContext *ctx, int tot) mvert = dm->getVertArray(dm); mface = dm->getTessFaceArray(dm); - origindex = dm->getTessFaceDataArray(dm, CD_ORIGINDEX); totface = dm->getNumTessFaces(dm); totorigface = me->totpoly; if (totface == 0 || totorigface == 0) return tot; + index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX); + index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX); + if ((index_mf_to_mpoly && index_mp_to_orig) == FALSE) { + index_mf_to_mpoly = index_mp_to_orig = NULL; + } + facearea = MEM_callocN(sizeof(float) * totorigface, "SimplifyFaceArea"); facecenter = MEM_callocN(sizeof(float[3]) * totorigface, "SimplifyFaceCenter"); facetotvert = MEM_callocN(sizeof(int) * totorigface, "SimplifyFaceArea"); @@ -824,20 +836,22 @@ int psys_render_simplify_distribution(ParticleThreadContext *ctx, int tot) data->do_simplify = TRUE; data->elems = elems; - data->origindex = origindex; + data->index_mf_to_mpoly = index_mf_to_mpoly; + data->index_mp_to_orig = index_mp_to_orig; /* compute number of children per original face */ for (a = 0; a < tot; a++) { - b = (origindex) ? origindex[ctx->index[a]] : ctx->index[a]; - if (b != -1) + b = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, ctx->index[a]) : ctx->index[a]; + if (b != ORIGINDEX_NONE) { elems[b].totchild++; + } } /* compute areas and centers of original faces */ for (mf = mface, a = 0; a < totface; a++, mf++) { - b = (origindex) ? origindex[a] : a; + b = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, a) : a; - if (b != -1) { + if (b != ORIGINDEX_NONE) { copy_v3_v3(co1, mvert[mf->v1].co); copy_v3_v3(co2, mvert[mf->v2].co); copy_v3_v3(co3, mvert[mf->v3].co); @@ -931,8 +945,9 @@ int psys_render_simplify_distribution(ParticleThreadContext *ctx, int tot) skipped = 0; for (a = 0, newtot = 0; a < tot; a++) { - b = (origindex) ? origindex[ctx->index[a]] : ctx->index[a]; - if (b != -1) { + b = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, ctx->index[a]) : ctx->index[a]; + + if (b != ORIGINDEX_NONE) { if (elems[b].curchild++ < ceil(elems[b].lambda * elems[b].totchild)) { ctx->index[newtot] = ctx->index[a]; ctx->skip[newtot] = skipped; @@ -963,10 +978,10 @@ int psys_render_simplify_params(ParticleSystem *psys, ChildParticle *cpa, float data = psys->renderdata; if (!data->do_simplify) return 0; - - b = (data->origindex) ? data->origindex[cpa->num] : cpa->num; - if (b == -1) + b = (data->index_mf_to_mpoly) ? DM_origindex_mface_mpoly(data->index_mf_to_mpoly, data->index_mp_to_orig, cpa->num) : cpa->num; + if (b == ORIGINDEX_NONE) { return 0; + } elem = &data->elems[b]; @@ -1624,17 +1639,22 @@ int psys_particle_dm_face_lookup(Object *ob, DerivedMesh *dm, int index, const f Mesh *me = (Mesh *)ob->data; MPoly *mpoly; OrigSpaceFace *osface; - int *origindex; int quad, findex, totface; float uv[2], (*faceuv)[2]; + /* double lookup */ + const int *index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX); + const int *index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX); + if ((index_mf_to_mpoly && index_mp_to_orig) == FALSE) { + index_mf_to_mpoly = index_mp_to_orig = NULL; + } + mpoly = dm->getPolyArray(dm); - origindex = dm->getTessFaceDataArray(dm, CD_ORIGINDEX); osface = dm->getTessFaceDataArray(dm, CD_ORIGSPACE); totface = dm->getNumTessFaces(dm); - if (osface == NULL || origindex == NULL) { + if (osface == NULL || index_mf_to_mpoly == NULL) { /* Assume we don't need osface data */ if (index < totface) { //printf("\tNO CD_ORIGSPACE, assuming not needed\n"); @@ -1668,7 +1688,8 @@ int psys_particle_dm_face_lookup(Object *ob, DerivedMesh *dm, int index, const f } else { /* if we have no node, try every face */ for (findex = 0; findex < totface; findex++) { - if (origindex[findex] == index) { + const int findex_orig = DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, findex); + if (findex_orig == index) { faceuv = osface[findex].uv; quad = (mpoly[findex].totloop == 4); diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 19ef83d53cf..e959ef35cb0 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -346,7 +346,7 @@ void psys_calc_dmcache(Object *ob, DerivedMesh *dm, ParticleSystem *psys) if (!dm->deformedOnly) { /* Will use later to speed up subsurf/derivedmesh */ LinkNode *node, *nodedmelem, **nodearray; - int totdmelem, totelem, i, *origindex; + int totdmelem, totelem, i, *origindex, *origindex_poly = NULL; if (psys->part->from == PART_FROM_VERT) { totdmelem= dm->getNumVerts(dm); @@ -356,23 +356,37 @@ void psys_calc_dmcache(Object *ob, DerivedMesh *dm, ParticleSystem *psys) else { /* FROM_FACE/FROM_VOLUME */ totdmelem= dm->getNumTessFaces(dm); totelem= me->totpoly; - origindex= dm->getTessFaceDataArray(dm, CD_ORIGINDEX); + origindex = dm->getTessFaceDataArray(dm, CD_ORIGINDEX); + /* for face lookups we need the poly origindex too */ + origindex_poly = dm->getPolyDataArray(dm, CD_ORIGINDEX); + if (origindex_poly == NULL) { + origindex = NULL; + } } nodedmelem= MEM_callocN(sizeof(LinkNode)*totdmelem, "psys node elems"); nodearray= MEM_callocN(sizeof(LinkNode *)*totelem, "psys node array"); for (i=0, node=nodedmelem; i<totdmelem; i++, origindex++, node++) { - node->link= SET_INT_IN_POINTER(i); + int origindex_final; + node->link = SET_INT_IN_POINTER(i); + + origindex_final = *origindex; + + /* if we have a poly source, do an index lookup */ + if (origindex_poly && origindex_final != ORIGINDEX_NONE) { + origindex_final = origindex_poly[origindex_final]; + } - if (*origindex != -1) { - if (nodearray[*origindex]) { + if (origindex_final != ORIGINDEX_NONE) { + if (nodearray[origindex_final]) { /* prepend */ - node->next = nodearray[*origindex]; - nodearray[*origindex] = node; + node->next = nodearray[origindex_final]; + nodearray[origindex_final] = node; + } + else { + nodearray[origindex_final] = node; } - else - nodearray[*origindex] = node; } } diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index cec676162f3..f195b3d71b0 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -2823,7 +2823,7 @@ PointCache *BKE_ptcache_copy_list(ListBase *ptcaches_new, ListBase *ptcaches_old } /* Disabled this code; this is being called on scene_update_tagged, and that in turn gets called on - every user action changing stuff, and then it runs a complete bake??? (ton) */ + * every user action changing stuff, and then it runs a complete bake??? (ton) */ /* Baking */ void BKE_ptcache_quick_cache_all(Main *bmain, Scene *scene) diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index 33350a80928..469b012f9c3 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -602,7 +602,7 @@ static void ss_sync_from_derivedmesh(CCGSubSurf *ss, DerivedMesh *dm, } mp = mpoly; - index = DM_get_poly_data_layer(dm, CD_ORIGINDEX); + index = (int *)dm->getPolyDataArray(dm, CD_ORIGINDEX); for (i = 0; i < dm->numPolyData; i++, mp++) { CCGFace *f; @@ -2706,6 +2706,30 @@ static void *ccgDM_get_tessface_data_layer(DerivedMesh *dm, int type) { if (type == CD_ORIGINDEX) { /* create origindex on demand to save memory */ + int *origindex; + + /* Avoid re-creation if the layer exists already */ + origindex = DM_get_tessface_data_layer(dm, CD_ORIGINDEX); + if (origindex) { + return origindex; + } + + DM_add_tessface_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL); + origindex = DM_get_tessface_data_layer(dm, CD_ORIGINDEX); + + /* silly loop counting up */ + range_vn_i(origindex, dm->getNumTessFaces(dm), 0); + + return origindex; + } + + return DM_get_tessface_data_layer(dm, type); +} + +static void *ccgDM_get_poly_data_layer(DerivedMesh *dm, int type) +{ + if (type == CD_ORIGINDEX) { + /* create origindex on demand to save memory */ CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm; CCGSubSurf *ss = ccgdm->ss; int *origindex; @@ -2713,13 +2737,13 @@ static void *ccgDM_get_tessface_data_layer(DerivedMesh *dm, int type) int gridFaces = ccgSubSurf_getGridSize(ss) - 1; /* Avoid re-creation if the layer exists already */ - origindex = DM_get_tessface_data_layer(dm, CD_ORIGINDEX); + origindex = DM_get_poly_data_layer(dm, CD_ORIGINDEX); if (origindex) { return origindex; } - DM_add_tessface_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL); - origindex = DM_get_tessface_data_layer(dm, CD_ORIGINDEX); + DM_add_poly_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL); + origindex = DM_get_poly_data_layer(dm, CD_ORIGINDEX); totface = ccgSubSurf_getNumFaces(ss); @@ -2735,7 +2759,7 @@ static void *ccgDM_get_tessface_data_layer(DerivedMesh *dm, int type) return origindex; } - return DM_get_tessface_data_layer(dm, type); + return DM_get_poly_data_layer(dm, type); } static void *ccgDM_get_vert_data(DerivedMesh *dm, int index, int type) @@ -2768,6 +2792,16 @@ static void *ccgDM_get_tessface_data(DerivedMesh *dm, int index, int type) return DM_get_tessface_data(dm, index, type); } +static void *ccgDM_get_poly_data(DerivedMesh *dm, int index, int type) +{ + if (type == CD_ORIGINDEX) { + /* ensure creation of CD_ORIGINDEX layer */ + ccgDM_get_tessface_data_layer(dm, type); + } + + return DM_get_poly_data(dm, index, type); +} + static int ccgDM_getNumGrids(DerivedMesh *dm) { CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm; @@ -3098,7 +3132,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, } /* We absolutely need that layer, else it's no valid tessellated data! */ - polyidx = CustomData_add_layer(&ccgdm->dm.faceData, CD_POLYINDEX, CD_CALLOC, + polyidx = CustomData_add_layer(&ccgdm->dm.faceData, CD_ORIGINDEX, CD_CALLOC, NULL, ccgSubSurf_getNumFinalFaces(ss)); ccgdm->dm.getMinMax = ccgDM_getMinMax; @@ -3126,9 +3160,11 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, ccgdm->dm.getVertData = ccgDM_get_vert_data; ccgdm->dm.getEdgeData = ccgDM_get_edge_data; ccgdm->dm.getTessFaceData = ccgDM_get_tessface_data; + ccgdm->dm.getPolyData = ccgDM_get_poly_data; ccgdm->dm.getVertDataArray = ccgDM_get_vert_data_layer; ccgdm->dm.getEdgeDataArray = ccgDM_get_edge_data_layer; ccgdm->dm.getTessFaceDataArray = ccgDM_get_tessface_data_layer; + ccgdm->dm.getPolyDataArray = ccgDM_get_poly_data_layer; ccgdm->dm.getNumGrids = ccgDM_getNumGrids; ccgdm->dm.getGridSize = ccgDM_getGridSize; ccgdm->dm.getGridData = ccgDM_getGridData; @@ -3227,8 +3263,8 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, vertOrigIndex = DM_get_vert_data_layer(&ccgdm->dm, CD_ORIGINDEX); /*edgeOrigIndex = DM_get_edge_data_layer(&ccgdm->dm, CD_ORIGINDEX);*/ - faceOrigIndex = DM_get_tessface_data_layer(&ccgdm->dm, CD_ORIGINDEX); + faceOrigIndex = DM_get_tessface_data_layer(&ccgdm->dm, CD_ORIGINDEX); polyOrigIndex = DM_get_poly_data_layer(&ccgdm->dm, CD_ORIGINDEX); #if 0 @@ -3366,7 +3402,8 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, /*set original index data*/ if (faceOrigIndex) { - *faceOrigIndex = origIndex; + /* reference the index in 'polyOrigIndex' */ + *faceOrigIndex = faceNum; faceOrigIndex++; } if (polyOrigIndex) { diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c index b9ca3c9cc63..b3497b9932f 100644 --- a/source/blender/blenkernel/intern/text.c +++ b/source/blender/blenkernel/intern/text.c @@ -55,12 +55,15 @@ #include "DNA_text_types.h" #include "DNA_userdef_types.h" #include "DNA_object_types.h" +#include "DNA_node_types.h" +#include "DNA_material_types.h" #include "BKE_depsgraph.h" #include "BKE_global.h" #include "BKE_library.h" #include "BKE_main.h" #include "BKE_text.h" +#include "BKE_node.h" #ifdef WITH_PYTHON @@ -531,6 +534,9 @@ void BKE_text_unlink(Main *bmain, Text *text) bController *cont; bActuator *act; bConstraint *con; + bNodeTree *ntree; + bNode *node; + Material *mat; short update; for (ob = bmain->object.first; ob; ob = ob->id.next) { @@ -582,6 +588,28 @@ void BKE_text_unlink(Main *bmain, Text *text) DAG_id_tag_update(&ob->id, OB_RECALC_DATA); } + /* nodes */ + for (mat = bmain->mat.first; mat; mat = mat->id.next) { + ntree = mat->nodetree; + if (!ntree) + continue; + for (node = ntree->nodes.first; node; node = node->next) { + if (node->type == SH_NODE_SCRIPT) { + Text *ntext = (Text *)node->id; + if (ntext == text) node->id = NULL; + } + } + } + + for (ntree = bmain->nodetree.first; ntree; ntree = ntree->id.next) { + for (node = ntree->nodes.first; node; node = node->next) { + if (node->type == SH_NODE_SCRIPT) { + Text *ntext = (Text *)node->id; + if (ntext == text) node->id = NULL; + } + } + } + /* text space */ for (scr = bmain->screen.first; scr; scr = scr->id.next) { for (area = scr->areabase.first; area; area = area->next) { diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c index efc7a281636..6d0313f6334 100644 --- a/source/blender/blenkernel/intern/texture.c +++ b/source/blender/blenkernel/intern/texture.c @@ -909,8 +909,7 @@ void autotexname(Tex *tex) if (tex->use_nodes) { new_id(&bmain->tex, (ID *)tex, "Noddy"); } - else - if (tex->type == TEX_IMAGE) { + else if (tex->type == TEX_IMAGE) { ima = tex->ima; if (ima) { BLI_strncpy(di, ima->name, sizeof(di)); diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index e39ad4a08c0..26775eaac8c 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -1189,17 +1189,17 @@ MovieTrackingObject *BKE_tracking_object_add(MovieTracking *tracking, const char return object; } -void BKE_tracking_object_delete(MovieTracking *tracking, MovieTrackingObject *object) +int BKE_tracking_object_delete(MovieTracking *tracking, MovieTrackingObject *object) { MovieTrackingTrack *track; int index = BLI_findindex(&tracking->objects, object); - if (index < 0) - return; + if (index == -1) + return FALSE; if (object->flag & TRACKING_OBJECT_CAMERA) { /* object used for camera solving can't be deleted */ - return; + return FALSE; } track = object->tracks.first; @@ -1215,10 +1215,11 @@ void BKE_tracking_object_delete(MovieTracking *tracking, MovieTrackingObject *ob tracking->tot_object--; - if (index > 0) + if (index != 0) tracking->objectnr = index - 1; else tracking->objectnr = 0; + return TRUE; } void BKE_tracking_object_unique_name(MovieTracking *tracking, MovieTrackingObject *object) diff --git a/source/blender/blenkernel/intern/unit.c b/source/blender/blenkernel/intern/unit.c index 46836b1f8d1..84e1f29f6c0 100644 --- a/source/blender/blenkernel/intern/unit.c +++ b/source/blender/blenkernel/intern/unit.c @@ -259,7 +259,7 @@ static struct bUnitCollection buNaturalTimeCollecton = {buNaturalTimeDef, 3, 0, static struct bUnitDef buNaturalRotDef[] = { - {"degree", "degrees", "°", NULL, "Degrees", M_PI/180.0, 0.0, B_UNIT_DEF_NONE}, + {"degree", "degrees", "°", NULL, "Degrees", M_PI / 180.0, 0.0, B_UNIT_DEF_NONE}, // {"radian", "radians", "r", NULL, "Radians", 1.0, 0.0, B_UNIT_DEF_NONE}, // {"turn", "turns", "t", NULL, "Turns", 1.0/(M_PI*2.0), 0.0,B_UNIT_DEF_NONE}, {NULL, NULL, NULL, NULL, NULL, 0.0, 0.0} diff --git a/source/blender/blenlib/BLI_math_matrix.h b/source/blender/blenlib/BLI_math_matrix.h index 8e9955beb61..9e34631d460 100644 --- a/source/blender/blenlib/BLI_math_matrix.h +++ b/source/blender/blenlib/BLI_math_matrix.h @@ -128,6 +128,7 @@ int is_orthonormal_m4(float mat[4][4]); int is_uniform_scaled_m3(float mat[3][3]); +void adjoint_m2_m2(float R[2][2], float A[2][2]); void adjoint_m3_m3(float R[3][3], float A[3][3]); void adjoint_m4_m4(float R[4][4], float A[4][4]); diff --git a/source/blender/blenlib/BLI_string.h b/source/blender/blenlib/BLI_string.h index ba906e1221c..70c89773f02 100644 --- a/source/blender/blenlib/BLI_string.h +++ b/source/blender/blenlib/BLI_string.h @@ -162,7 +162,7 @@ __attribute__((nonnull)) #endif ; -size_t BLI_strescape(char *__restrict dst, const char *__restrict src, const size_t maxlen) +size_t BLI_strescape(char *__restrict dst, const char *__restrict src, const size_t maxncpy) #ifdef __GNUC__ __attribute__((nonnull)) #endif diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c index fe91f91320a..70617453eff 100644 --- a/source/blender/blenlib/intern/BLI_kdopbvh.c +++ b/source/blender/blenlib/intern/BLI_kdopbvh.c @@ -1104,7 +1104,9 @@ BVHTreeOverlap *BLI_bvhtree_overlap(BVHTree *tree1, BVHTree *tree2, unsigned int if (!tree_overlap(tree1->nodes[tree1->totleaf], tree2->nodes[tree2->totleaf], min_axis(tree1->start_axis, tree2->start_axis), min_axis(tree1->stop_axis, tree2->stop_axis))) + { return NULL; + } data = MEM_callocN(sizeof(BVHOverlapData *) * tree1->tree_type, "BVHOverlapData_star"); diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c index f4a65564fd4..2b7c23ce67e 100644 --- a/source/blender/blenlib/intern/math_matrix.c +++ b/source/blender/blenlib/intern/math_matrix.c @@ -945,8 +945,18 @@ void normalize_m4_m4(float rmat[][4], float mat[][4]) if (len != 0.0f) rmat[2][3] = mat[2][3] / len; } +void adjoint_m2_m2(float m1[][2], float m[][2]) +{ + BLI_assert(m1 != m); + m1[0][0] = m[1][1]; + m1[0][1] = -m[1][0]; + m1[1][0] = -m[0][1]; + m1[1][1] = m[0][0]; +} + void adjoint_m3_m3(float m1[][3], float m[][3]) { + BLI_assert(m1 != m); m1[0][0] = m[1][1] * m[2][2] - m[1][2] * m[2][1]; m1[0][1] = -m[0][1] * m[2][2] + m[0][2] * m[2][1]; m1[0][2] = m[0][1] * m[1][2] - m[0][2] * m[1][1]; diff --git a/source/blender/blenlib/intern/math_rotation.c b/source/blender/blenlib/intern/math_rotation.c index 70d9ef27734..589e6462f62 100644 --- a/source/blender/blenlib/intern/math_rotation.c +++ b/source/blender/blenlib/intern/math_rotation.c @@ -234,7 +234,7 @@ void quat_to_mat4(float m[][4], const float q[4]) double q0, q1, q2, q3, qda, qdb, qdc, qaa, qab, qac, qbb, qbc, qcc; #ifdef DEBUG - if (!((q0 = dot_qtqt(q, q)) == 0.0f || (fabsf(q0 - 1.0) < QUAT_EPSILON))) { + if (!((q0 = dot_qtqt(q, q)) == 0.0f || (fabsf(q0 - 1.0) < (float)QUAT_EPSILON))) { fprintf(stderr, "Warning! quat_to_mat4() called with non-normalized: size %.8f *** report a bug ***\n", (float)q0); } #endif @@ -1077,11 +1077,11 @@ void compatible_eul(float eul[3], const float oldrot[3]) for (i = 0; i < 3; i++) { deul[i] = eul[i] - oldrot[i]; if (deul[i] > pi_thresh) { - eul[i] -= floorf(( deul[i] / pi_x2) + 0.5) * pi_x2; + eul[i] -= floorf(( deul[i] / pi_x2) + 0.5f) * pi_x2; deul[i] = eul[i] - oldrot[i]; } else if (deul[i] < -pi_thresh) { - eul[i] += floorf((-deul[i] / pi_x2) + 0.5) * pi_x2; + eul[i] += floorf((-deul[i] / pi_x2) + 0.5f) * pi_x2; deul[i] = eul[i] - oldrot[i]; } } diff --git a/source/blender/blenlib/intern/noise.c b/source/blender/blenlib/intern/noise.c index 124624ca137..fb33d7ce127 100644 --- a/source/blender/blenlib/intern/noise.c +++ b/source/blender/blenlib/intern/noise.c @@ -301,8 +301,8 @@ static float newPerlin(float x, float y, float z) u = npfade(x); /* COMPUTE FADE CURVES */ v = npfade(y); /* FOR EACH OF X,Y,Z. */ w = npfade(z); - A = hash[X ]+Y; AA = hash[A]+Z; AB = hash[A+1]+Z; /* HASH COORDINATES OF */ - B = hash[X+1]+Y; BA = hash[B]+Z; BB = hash[B+1]+Z; /* THE 8 CUBE CORNERS, */ + A = hash[X ] + Y; AA = hash[A] + Z; AB = hash[A + 1] + Z; /* HASH COORDINATES OF */ + B = hash[X + 1] + Y; BA = hash[B] + Z; BB = hash[B + 1] + Z; /* THE 8 CUBE CORNERS, */ return lerp(w, lerp(v, lerp(u, grad(hash[AA ], x, y, z ), /* AND ADD */ grad(hash[BA ], x - 1, y, z )), /* BLENDED */ lerp(u, grad(hash[AB ], x, y - 1, z ), /* RESULTS */ diff --git a/source/blender/blenlib/intern/string.c b/source/blender/blenlib/intern/string.c index 73d88ddd259..ff589764287 100644 --- a/source/blender/blenlib/intern/string.c +++ b/source/blender/blenlib/intern/string.c @@ -41,6 +41,8 @@ #include "BLI_dynstr.h" #include "BLI_string.h" +#include "BLI_utildefines.h" + char *BLI_strdupn(const char *str, const size_t len) { char *n = MEM_mallocN(len + 1, "strdup"); @@ -71,6 +73,7 @@ char *BLI_strncpy(char *dst, const char *src, const size_t maxncpy) { size_t srclen = strlen(src); size_t cpylen = (srclen > (maxncpy - 1)) ? (maxncpy - 1) : srclen; + BLI_assert(maxncpy != 0); memcpy(dst, src, cpylen); dst[cpylen] = '\0'; @@ -130,10 +133,13 @@ char *BLI_sprintfN(const char *format, ...) * TODO: support more fancy string escaping. current code is primitive * this basically is an ascii version of PyUnicode_EncodeUnicodeEscape() * which is a useful reference. */ -size_t BLI_strescape(char *dst, const char *src, const size_t maxlen) +size_t BLI_strescape(char *dst, const char *src, const size_t maxncpy) { size_t len = 0; - while (len < maxlen) { + + BLI_assert(maxncpy != 0); + + while (len < maxncpy) { switch (*src) { case '\0': goto escape_finish; @@ -144,7 +150,7 @@ size_t BLI_strescape(char *dst, const char *src, const size_t maxlen) case '\t': case '\n': case '\r': - if (len + 1 < maxlen) { + if (len + 1 < maxncpy) { *dst++ = '\\'; len++; } @@ -439,4 +445,3 @@ void BLI_ascii_strtoupper(char *str, const size_t len) if (str[i] >= 'a' && str[i] <= 'z') str[i] -= 'a' - 'A'; } - diff --git a/source/blender/blenlib/intern/string_utf8.c b/source/blender/blenlib/intern/string_utf8.c index 5684b12cc8b..0b737e0eff5 100644 --- a/source/blender/blenlib/intern/string_utf8.c +++ b/source/blender/blenlib/intern/string_utf8.c @@ -33,8 +33,12 @@ #include <string.h> #include <wchar.h> #include <wctype.h> +#include <stdio.h> +#include <stdlib.h> -#include "BLI_string_utf8.h" +#include "BLI_utildefines.h" + +#include "BLI_string_utf8.h" /* own include */ /* from libswish3, originally called u8_isvalid(), * modified to return the index of the bad character (byte index not utf). @@ -153,14 +157,14 @@ int BLI_utf8_invalid_strip(char *str, int length) * note: this looks to be at odd's with 'trailingBytesForUTF8', * need to find out what gives here! - campbell */ static const size_t utf8_skip_data[256] = { - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 1, 1 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 1, 1 }; #define BLI_STR_UTF8_CPY(dst, src, maxncpy) \ @@ -184,6 +188,8 @@ char *BLI_strncpy_utf8(char *dst, const char *src, size_t maxncpy) { char *dst_r = dst; + BLI_assert(maxncpy != 0); + /* note: currently we don't attempt to deal with invalid utf8 chars */ BLI_STR_UTF8_CPY(dst, src, maxncpy); @@ -207,10 +213,13 @@ char *BLI_strncat_utf8(char *dst, const char *src, size_t maxncpy) /* --------------------------------------------------------------------------*/ /* wchar_t / utf8 functions */ -size_t BLI_strncpy_wchar_as_utf8(char *dst, const wchar_t *src, const size_t maxcpy) +size_t BLI_strncpy_wchar_as_utf8(char *dst, const wchar_t *src, const size_t maxncpy) { size_t len = 0; - while (*src && len < maxcpy) { /* XXX can still run over the buffer because utf8 size isn't known :| */ + + BLI_assert(maxncpy != 0); + + while (*src && len < maxncpy) { /* XXX can still run over the buffer because utf8 size isn't known :| */ len += BLI_str_utf8_from_unicode(*src++, dst + len); } @@ -280,7 +289,7 @@ size_t BLI_strnlen_utf8(const char *start, const size_t maxlen) return len; } -size_t BLI_strncpy_wchar_from_utf8(wchar_t *dst_w, const char *src_c, const size_t maxcpy) +size_t BLI_strncpy_wchar_from_utf8(wchar_t *dst_w, const char *src_c, const size_t maxncpy) { int len = 0; @@ -288,7 +297,7 @@ size_t BLI_strncpy_wchar_from_utf8(wchar_t *dst_w, const char *src_c, const size return 0; } - while (*src_c && len < maxcpy) { + while (*src_c && len < maxncpy) { size_t step = 0; unsigned int unicode = BLI_str_utf8_as_unicode_and_size(src_c, &step); if (unicode != BLI_UTF8_ERR) { diff --git a/source/blender/blenlib/intern/voronoi.c b/source/blender/blenlib/intern/voronoi.c index 9674012a73d..0d411038b3e 100644 --- a/source/blender/blenlib/intern/voronoi.c +++ b/source/blender/blenlib/intern/voronoi.c @@ -39,7 +39,7 @@ #include "BLI_voronoi.h" #include "BLI_utildefines.h" -#define VORONOI_EPS 1e-2 +#define VORONOI_EPS 1e-2f enum { voronoiEventType_Site = 0, diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 8929fa3ff7a..0b9421d2b12 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -2430,8 +2430,18 @@ static void direct_link_nodetree(FileData *fd, bNodeTree *ntree) if (node->storage) { /* could be handlerized at some point */ - if (ntree->type==NTREE_SHADER && (node->type==SH_NODE_CURVE_VEC || node->type==SH_NODE_CURVE_RGB)) + if (ntree->type==NTREE_SHADER) { + if (node->type==SH_NODE_CURVE_VEC || node->type==SH_NODE_CURVE_RGB) { direct_link_curvemapping(fd, node->storage); + } + else if (node->type==SH_NODE_SCRIPT) { + NodeShaderScript *nss = (NodeShaderScript *) node->storage; + nss->bytecode = newdataadr(fd, nss->bytecode); + nss->prop = newdataadr(fd, nss->prop); + if (nss->prop) + IDP_DirectLinkProperty(nss->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd); + } + } else if (ntree->type==NTREE_COMPOSIT) { if (ELEM4(node->type, CMP_NODE_TIME, CMP_NODE_CURVE_VEC, CMP_NODE_CURVE_RGB, CMP_NODE_HUECORRECT)) direct_link_curvemapping(fd, node->storage); @@ -3730,7 +3740,7 @@ static void lib_link_mesh(FileData *fd, Main *main) /* * Re-tessellate, even if the polys were just created from tessfaces, this * is important because it: - * - fill the CD_POLYINDEX layer + * - fill the CD_ORIGINDEX layer * - gives consistency of tessface between loading from a file and * converting an edited BMesh back into a mesh (i.e. it replaces * quad tessfaces in a loaded mesh immediately, instead of lazily @@ -3825,7 +3835,7 @@ static void direct_link_customdata(FileData *fd, CustomData *data, int count) /* annoying workaround for bug [#31079] loading legacy files with * no polygons _but_ have stale customdata */ if (UNLIKELY(count == 0 && data->layers == NULL && data->totlayer != 0)) { - memset(data, 0, sizeof(*data)); + CustomData_reset(data); return; } @@ -7327,6 +7337,29 @@ static void do_version_node_fix_internal_links_264(void *UNUSED(data), ID *UNUSE } } +static void do_version_logic_264(ListBase *regionbase) +{ + ARegion *ar; + + /* view settings for logic changed */ + for (ar = regionbase->first; ar; ar = ar->next) { + if (ar->regiontype == RGN_TYPE_WINDOW) { + if (ar->v2d.keeptot == 0) { + ar->v2d.maxzoom = 1.5f; + + ar->v2d.keepzoom = V2D_KEEPZOOM | V2D_LIMITZOOM | V2D_KEEPASPECT; + ar->v2d.keeptot = V2D_KEEPTOT_BOUNDS; + ar->v2d.align = V2D_ALIGN_NO_POS_Y | V2D_ALIGN_NO_NEG_X; + ar->v2d.keepofs = V2D_KEEPOFS_Y; + } + } + } + + +} + + + static void do_versions(FileData *fd, Library *lib, Main *main) { /* WATCH IT!!!: pointers from libdata have not been converted */ @@ -8264,6 +8297,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main) { Mesh *me; for (me = main->mesh.first; me; me = me->id.next) { + CustomData_update_typemap(&me->vdata); CustomData_free_layers(&me->vdata, CD_MSTICKY, me->totvert); } } @@ -8436,6 +8470,35 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } + if (main->versionfile < 264 || (main->versionfile == 264 && main->subversionfile < 6)) { + bScreen *sc; + + for (sc = main->screen.first; sc; sc = sc->id.next) { + ScrArea *sa; + for (sa = sc->areabase.first; sa; sa = sa->next) { + SpaceLink *sl; + if ( sa->spacetype == SPACE_LOGIC) + do_version_logic_264(&sa->regionbase); + + for (sl = sa->spacedata.first; sl; sl = sl->next) { + if (sl->spacetype == SPACE_LOGIC) + do_version_logic_264(&sl->regionbase); + } + } + } + + } + + { + Object *ob; + for (ob = main->object.first; ob; ob = ob->id.next) { + if (ob->col_group == 0) { + ob->col_group = 0x01; + ob->col_mask = 0xff; + } + } + } + /* default values in Freestyle settings */ { Scene *sce; diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index ea8b566340d..d67f45cde10 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -729,6 +729,16 @@ static void write_nodetree(WriteData *wd, bNodeTree *ntree) /* could be handlerized at some point, now only 1 exception still */ if (ntree->type==NTREE_SHADER && (node->type==SH_NODE_CURVE_VEC || node->type==SH_NODE_CURVE_RGB)) write_curvemapping(wd, node->storage); + else if (ntree->type==NTREE_SHADER && node->type==SH_NODE_SCRIPT) { + NodeShaderScript *nss = (NodeShaderScript *)node->storage; + if (nss->bytecode) + writedata(wd, DATA, strlen(nss->bytecode)+1, nss->bytecode); + /* Write ID Properties -- and copy this comment EXACTLY for easy finding + * of library blocks that implement this.*/ + if (nss->prop) + IDP_WriteProperty(nss->prop, wd); + writestruct(wd, DATA, node->typeinfo->storagename, 1, node->storage); + } else if (ntree->type==NTREE_COMPOSIT && ELEM4(node->type, CMP_NODE_TIME, CMP_NODE_CURVE_VEC, CMP_NODE_CURVE_RGB, CMP_NODE_HUECORRECT)) write_curvemapping(wd, node->storage); else if (ntree->type==NTREE_TEXTURE && (node->type==TEX_NODE_CURVE_RGB || node->type==TEX_NODE_CURVE_TIME) ) @@ -1732,9 +1742,10 @@ static void write_customdata(WriteData *wd, ID *id, int count, CustomData *data, writestruct(wd, DATA, structname, datasize, layer->data); } - else + else { printf("%s error: layer '%s':%d - can't be written to file\n", __func__, structname, layer->type); + } } } @@ -1766,6 +1777,9 @@ static void write_meshs(WriteData *wd, ListBase *idbase) backup_mesh.totface = mesh->totface; mesh->totface = 0; /* -- */ + backup_mesh.fdata = mesh->fdata; + memset(&mesh->fdata, 0, sizeof(mesh->fdata)); + /* -- */ #endif /* USE_BMESH_SAVE_WITHOUT_MFACE */ writestruct(wd, ID_ME, "Mesh", 1, mesh); @@ -1789,6 +1803,8 @@ static void write_meshs(WriteData *wd, ListBase *idbase) mesh->mface = backup_mesh.mface; /* -- */ mesh->totface = backup_mesh.totface; + /* -- */ + mesh->fdata = backup_mesh.fdata; #endif /* USE_BMESH_SAVE_WITHOUT_MFACE */ } diff --git a/source/blender/bmesh/CMakeLists.txt b/source/blender/bmesh/CMakeLists.txt index f811dcf956e..d7858ebbc0d 100644 --- a/source/blender/bmesh/CMakeLists.txt +++ b/source/blender/bmesh/CMakeLists.txt @@ -30,7 +30,9 @@ set(INC ../blenlib ../makesdna ../../../intern/guardedalloc - ../../../extern/bullet2/src ../../../intern/opennl/extern) + ../../../extern/bullet2/src + ../../../intern/opennl/extern +) set(INC_SYS @@ -52,6 +54,7 @@ set(SRC operators/bmo_mirror.c operators/bmo_primitive.c operators/bmo_removedoubles.c + operators/bmo_similar.c operators/bmo_smooth_laplacian.c operators/bmo_symmetrize.c operators/bmo_subdivide.c diff --git a/source/blender/bmesh/intern/bmesh_decimate_collapse.c b/source/blender/bmesh/intern/bmesh_decimate_collapse.c index fbdbe2ffe94..feeb2a926f3 100644 --- a/source/blender/bmesh/intern/bmesh_decimate_collapse.c +++ b/source/blender/bmesh/intern/bmesh_decimate_collapse.c @@ -52,9 +52,9 @@ #define BOUNDARY_PRESERVE_WEIGHT 100.0f typedef enum CD_UseFlag { - CD_DO_VERT, - CD_DO_EDGE, - CD_DO_LOOP + CD_DO_VERT = (1 << 0), + CD_DO_EDGE = (1 << 1), + CD_DO_LOOP = (1 << 2) } CD_UseFlag; diff --git a/source/blender/bmesh/intern/bmesh_decimate_dissolve.c b/source/blender/bmesh/intern/bmesh_decimate_dissolve.c index 91eac527047..d1371a18160 100644 --- a/source/blender/bmesh/intern/bmesh_decimate_dissolve.c +++ b/source/blender/bmesh/intern/bmesh_decimate_dissolve.c @@ -179,10 +179,10 @@ void BM_mesh_decimate_dissolve_ex(BMesh *bm, const float angle_limit, const int /* simple version of the branch below, sincve we will dissolve _all_ verts that use 2 edges */ for (i = 0; i < vinput_len; i++) { BMVert *v = vinput_arr[i]; - if (v) { - if (BM_vert_edge_count(v) == 2) { - BM_vert_collapse_edge(bm, v->e, v, TRUE); /* join edges */ - } + if (LIKELY(v != NULL) && + BM_vert_edge_count(v) == 2) + { + BM_vert_collapse_edge(bm, v->e, v, TRUE); /* join edges */ } } } @@ -207,10 +207,11 @@ void BM_mesh_decimate_dissolve_ex(BMesh *bm, const float angle_limit, const int for (i = 0; i < tot_found; i++) { BMVert *v = (BMVert *)weight_elems[i].ele; - if (/* topology changes may cause this to be un-collapsable */ - (BM_vert_edge_count(v) == 2) && - /* check twice because cumulative effect could dissolve over angle limit */ - bm_vert_edge_face_angle(v) < angle_limit) + if (LIKELY(v != NULL) && + /* topology changes may cause this to be un-collapsable */ + (BM_vert_edge_count(v) == 2) && + /* check twice because cumulative effect could dissolve over angle limit */ + bm_vert_edge_face_angle(v) < angle_limit) { BMEdge *ne = BM_vert_collapse_edge(bm, v->e, v, TRUE); /* join edges */ diff --git a/source/blender/bmesh/intern/bmesh_interp.c b/source/blender/bmesh/intern/bmesh_interp.c index ffe79923730..508b3b8fcdf 100644 --- a/source/blender/bmesh/intern/bmesh_interp.c +++ b/source/blender/bmesh/intern/bmesh_interp.c @@ -224,10 +224,8 @@ static int compute_mdisp_quad(BMLoop *l, float v1[3], float v2[3], float v3[3], /* computer center */ BM_face_calc_center_mean(l->f, cent); - add_v3_v3v3(p, l->prev->v->co, l->v->co); - mul_v3_fl(p, 0.5); - add_v3_v3v3(n, l->next->v->co, l->v->co); - mul_v3_fl(n, 0.5); + mid_v3_v3v3(p, l->prev->v->co, l->v->co); + mid_v3_v3v3(n, l->next->v->co, l->v->co); copy_v3_v3(v1, cent); copy_v3_v3(v2, p); @@ -525,8 +523,7 @@ void BM_face_multires_bounds_smooth(BMesh *bm, BMFace *f) sides = (int)sqrt(mdp->totdisp); for (y = 0; y < sides; y++) { - add_v3_v3v3(co1, mdn->disps[y * sides], mdl->disps[y]); - mul_v3_fl(co1, 0.5); + mid_v3_v3v3(co1, mdn->disps[y * sides], mdl->disps[y]); copy_v3_v3(mdn->disps[y * sides], co1); copy_v3_v3(mdl->disps[y], co1); diff --git a/source/blender/bmesh/intern/bmesh_marking.c b/source/blender/bmesh/intern/bmesh_marking.c index e4a838fe893..9af65d7dd7e 100644 --- a/source/blender/bmesh/intern/bmesh_marking.c +++ b/source/blender/bmesh/intern/bmesh_marking.c @@ -584,8 +584,7 @@ void BM_editselection_center(BMEditSelection *ese, float r_center[3]) } else if (ese->htype == BM_EDGE) { BMEdge *eed = (BMEdge *)ese->ele; - add_v3_v3v3(r_center, eed->v1->co, eed->v2->co); - mul_v3_fl(r_center, 0.5); + mid_v3_v3v3(r_center, eed->v1->co, eed->v2->co); } else if (ese->htype == BM_FACE) { BMFace *efa = (BMFace *)ese->ele; diff --git a/source/blender/bmesh/intern/bmesh_mesh.c b/source/blender/bmesh/intern/bmesh_mesh.c index 32879caec71..d3e3bcd3556 100644 --- a/source/blender/bmesh/intern/bmesh_mesh.c +++ b/source/blender/bmesh/intern/bmesh_mesh.c @@ -85,6 +85,11 @@ BMesh *BM_mesh_create(BMAllocTemplate *allocsize) bm->stackdepth = 1; bm->totflags = 1; + CustomData_reset(&bm->vdata); + CustomData_reset(&bm->edata); + CustomData_reset(&bm->ldata); + CustomData_reset(&bm->pdata); + return bm; } diff --git a/source/blender/bmesh/intern/bmesh_mesh_conv.c b/source/blender/bmesh/intern/bmesh_mesh_conv.c index b0a9168ffda..62abf43829b 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_conv.c +++ b/source/blender/bmesh/intern/bmesh_mesh_conv.c @@ -536,7 +536,9 @@ void BM_mesh_bm_to_me(BMesh *bm, Mesh *me, int dotess) oldverts = me->mvert; /* don't free this yet */ - CustomData_set_layer(&me->vdata, CD_MVERT, NULL); + if (oldverts) { + CustomData_set_layer(&me->vdata, CD_MVERT, NULL); + } /* free custom data */ CustomData_free(&me->vdata, me->totvert); diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c index e12e28f8cff..31698f0abc1 100644 --- a/source/blender/bmesh/intern/bmesh_opdefines.c +++ b/source/blender/bmesh/intern/bmesh_opdefines.c @@ -822,10 +822,11 @@ static BMOpDefine bmo_spin_def = { */ static BMOpDefine bmo_similar_faces_def = { "similar_faces", - {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */ - {BMO_OP_SLOT_ELEMENT_BUF, "faceout"}, /* output faces */ - {BMO_OP_SLOT_INT, "type"}, /* type of selection */ - {BMO_OP_SLOT_FLT, "thresh"}, /* threshold of selection */ + {{BMO_OP_SLOT_ELEMENT_BUF, "faces"}, /* input faces */ + {BMO_OP_SLOT_ELEMENT_BUF, "faceout"}, /* output faces */ + {BMO_OP_SLOT_INT, "type"}, /* type of selection */ + {BMO_OP_SLOT_FLT, "thresh"}, /* threshold of selection */ + {BMO_OP_SLOT_INT, "compare"}, /* comparison method */ {0} /* null-terminating sentinel */}, bmo_similar_faces_exec, 0 @@ -838,10 +839,11 @@ static BMOpDefine bmo_similar_faces_def = { */ static BMOpDefine bmo_similar_edges_def = { "similar_edges", - {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edges */ - {BMO_OP_SLOT_ELEMENT_BUF, "edgeout"}, /* output edges */ - {BMO_OP_SLOT_INT, "type"}, /* type of selection */ - {BMO_OP_SLOT_FLT, "thresh"}, /* threshold of selection */ + {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, /* input edges */ + {BMO_OP_SLOT_ELEMENT_BUF, "edgeout"}, /* output edges */ + {BMO_OP_SLOT_INT, "type"}, /* type of selection */ + {BMO_OP_SLOT_FLT, "thresh"}, /* threshold of selection */ + {BMO_OP_SLOT_INT, "compare"}, /* comparison method */ {0} /* null-terminating sentinel */}, bmo_similar_edges_exec, 0 @@ -854,10 +856,11 @@ static BMOpDefine bmo_similar_edges_def = { */ static BMOpDefine bmo_similar_verts_def = { "similar_verts", - {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertices */ - {BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, /* output vertices */ - {BMO_OP_SLOT_INT, "type"}, /* type of selection */ - {BMO_OP_SLOT_FLT, "thresh"}, /* threshold of selection */ + {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertices */ + {BMO_OP_SLOT_ELEMENT_BUF, "vertout"}, /* output vertices */ + {BMO_OP_SLOT_INT, "type"}, /* type of selection */ + {BMO_OP_SLOT_FLT, "thresh"}, /* threshold of selection */ + {BMO_OP_SLOT_INT, "compare"}, /* comparison method */ {0} /* null-terminating sentinel */}, bmo_similar_verts_exec, 0 diff --git a/source/blender/bmesh/intern/bmesh_operators.c b/source/blender/bmesh/intern/bmesh_operators.c index 015052e685d..2413f3a7be0 100644 --- a/source/blender/bmesh/intern/bmesh_operators.c +++ b/source/blender/bmesh/intern/bmesh_operators.c @@ -1026,7 +1026,7 @@ static void bmo_flag_layer_alloc(BMesh *bm) int i; BMIter iter; - BLI_mempool *oldpool = bm->toolflagpool; /* old flag pool */ + BLI_mempool *oldpool = bm->toolflagpool; /* old flag pool */ BLI_mempool *newpool; void *oldflags; diff --git a/source/blender/bmesh/intern/bmesh_operators.h b/source/blender/bmesh/intern/bmesh_operators.h index 05113576ca4..79b8c450fd9 100644 --- a/source/blender/bmesh/intern/bmesh_operators.h +++ b/source/blender/bmesh/intern/bmesh_operators.h @@ -46,11 +46,18 @@ enum { SUBDIV_SELECT_LOOPCUT }; +enum { + SIM_CMP_EQ = 0, + SIM_CMP_GT, + SIM_CMP_LT +}; + /* similar face selection slot values */ enum { SIMFACE_MATERIAL = 201, SIMFACE_IMAGE, SIMFACE_AREA, + SIMFACE_SIDES, SIMFACE_PERIMETER, SIMFACE_NORMAL, SIMFACE_COPLANAR, diff --git a/source/blender/bmesh/intern/bmesh_polygon.c b/source/blender/bmesh/intern/bmesh_polygon.c index bd0f93ee7aa..98edceb30a2 100644 --- a/source/blender/bmesh/intern/bmesh_polygon.c +++ b/source/blender/bmesh/intern/bmesh_polygon.c @@ -313,7 +313,7 @@ void poly_rotate_plane(const float normal[3], float (*verts)[3], const int nvert float up[3] = {0.0f, 0.0f, 1.0f}, axis[3], q[4]; float mat[3][3]; - double angle; + float angle; int i; cross_v3_v3v3(axis, normal, up); @@ -329,7 +329,7 @@ void poly_rotate_plane(const float normal[3], float (*verts)[3], const int nvert axis[2] = 0.0f; } - axis_angle_to_quat(q, axis, (float)angle); + axis_angle_to_quat(q, axis, angle); quat_to_mat3(mat, q); for (i = 0; i < nverts; i++) diff --git a/source/blender/bmesh/intern/bmesh_queries.c b/source/blender/bmesh/intern/bmesh_queries.c index fbbb9c2a825..4b07dd74eef 100644 --- a/source/blender/bmesh/intern/bmesh_queries.c +++ b/source/blender/bmesh/intern/bmesh_queries.c @@ -344,7 +344,7 @@ BMLoop *BM_edge_other_loop(BMEdge *e, BMLoop *l) BMLoop *l_other; // BLI_assert(BM_edge_is_manifold(e)); // TOO strict, just check if we have another radial face - BLI_assert(e->l && e->l->radial_next != l); + BLI_assert(e->l && e->l->radial_next != e->l); BLI_assert(BM_vert_in_edge(e, l->v)); l_other = (l->e == e) ? l : l->prev; diff --git a/source/blender/bmesh/intern/bmesh_walkers_impl.c b/source/blender/bmesh/intern/bmesh_walkers_impl.c index bb1e599f097..bb013e6428e 100644 --- a/source/blender/bmesh/intern/bmesh_walkers_impl.c +++ b/source/blender/bmesh/intern/bmesh_walkers_impl.c @@ -598,7 +598,7 @@ static void *bmw_LoopWalker_step(BMWalker *walker) } } } - else { /* WIRE EDGE */ + else { /* WIRE EDGE */ BMIter eiter; /* match trunk: mark all connected wire edges */ diff --git a/source/blender/bmesh/operators/bmo_primitive.c b/source/blender/bmesh/operators/bmo_primitive.c index 30561e47d20..d7b163cb760 100644 --- a/source/blender/bmesh/operators/bmo_primitive.c +++ b/source/blender/bmesh/operators/bmo_primitive.c @@ -365,7 +365,7 @@ void bmo_create_uvsphere_exec(BMesh *bm, BMOperator *op) len2 = len_v3v3(vec, vec2); /* use shortest segment length divided by 3 as merge threshold */ - BMO_op_callf(bm, op->flag, "remove_doubles verts=%fv dist=%f", VERT_MARK, MIN2(len, len2) / 3.0f); + BMO_op_callf(bm, op->flag, "remove_doubles verts=%fv dist=%f", VERT_MARK, min_ff(len, len2) / 3.0f); } /* and now do imat */ diff --git a/source/blender/bmesh/operators/bmo_removedoubles.c b/source/blender/bmesh/operators/bmo_removedoubles.c index d3e98dd96c1..cd792f911a9 100644 --- a/source/blender/bmesh/operators/bmo_removedoubles.c +++ b/source/blender/bmesh/operators/bmo_removedoubles.c @@ -371,7 +371,7 @@ void bmo_collapse_exec(BMesh *bm, BMOperator *op) BMIter iter; BMEdge *e, **edges = NULL; BLI_array_declare(edges); - float min[3], max[3]; + float min[3], max[3], center[3]; int i, tot; BMO_op_callf(bm, op->flag, "collapse_uvs edges=%s", op, "edges"); @@ -400,13 +400,12 @@ void bmo_collapse_exec(BMesh *bm, BMOperator *op) minmax_v3v3_v3(min, max, e->v2->co); } - add_v3_v3v3(min, min, max); - mul_v3_fl(min, 0.5f); + mid_v3_v3v3(center, min, max); /* snap edges to a point. for initial testing purposes anyway */ for (i = 0; i < tot; i++) { - copy_v3_v3(edges[i]->v1->co, min); - copy_v3_v3(edges[i]->v2->co, min); + copy_v3_v3(edges[i]->v1->co, center); + copy_v3_v3(edges[i]->v2->co, center); if (edges[i]->v1 != edges[0]->v1) BMO_slot_map_ptr_insert(bm, &weldop, "targetmap", edges[i]->v1, edges[0]->v1); diff --git a/source/blender/bmesh/operators/bmo_similar.c b/source/blender/bmesh/operators/bmo_similar.c new file mode 100644 index 00000000000..b4566f6c8a9 --- /dev/null +++ b/source/blender/bmesh/operators/bmo_similar.c @@ -0,0 +1,620 @@ +/* + * ***** 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, Campbell Barton + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/bmesh/operators/bmo_similar.c + * \ingroup bmesh + * + * bmesh operators to select based on + * comparisons with the existing selection. + */ + +#include "MEM_guardedalloc.h" + +#include "DNA_object_types.h" +#include "DNA_meshdata_types.h" + +#include "BLI_math.h" + +#include "BKE_customdata.h" +#include "BKE_deform.h" + +#include "bmesh.h" + +#include "intern/bmesh_operators_private.h" /* own include */ + +/* in fact these could all be the same */ + +/* + * extra face data (computed data) + */ +typedef struct SimSel_FaceExt { + BMFace *f; /* the face */ + float c[3]; /* center */ + union { + float area; /* area */ + float perim; /* perimeter */ + float d; /* 4th component of plane (the first three being the normal) */ + struct Image *t; /* image pointer */ + }; +} SimSel_FaceExt; + +static int bm_sel_similar_cmp_fl(const float delta, const float thresh, const int compare) +{ + switch (compare) { + case SIM_CMP_EQ: + return (fabsf(delta) <= thresh); + case SIM_CMP_GT: + return ((delta + thresh) >= 0.0f); + case SIM_CMP_LT: + return ((delta - thresh) <= 0.0f); + default: + BLI_assert(0); + return 0; + } +} + +static int bm_sel_similar_cmp_i(const int delta, const int compare) +{ + switch (compare) { + case SIM_CMP_EQ: + return (delta == 0); + case SIM_CMP_GT: + return (delta > 0); + case SIM_CMP_LT: + return (delta < 0); + default: + BLI_assert(0); + return 0; + } +} + +/* + * Select similar faces, the choices are in the enum in source/blender/bmesh/bmesh_operators.h + * We select either similar faces based on material, image, area, perimeter, normal, or the coplanar faces + */ +void bmo_similar_faces_exec(BMesh *bm, BMOperator *op) +{ +#define FACE_MARK 1 + + BMIter fm_iter; + BMFace *fs, *fm; + BMOIter fs_iter; + int num_sels = 0, num_total = 0, i = 0, idx = 0; + float angle = 0.0f; + SimSel_FaceExt *f_ext = NULL; + int *indices = NULL; + float t_no[3]; /* temporary normal */ + const int type = BMO_slot_int_get(op, "type"); + const float thresh = BMO_slot_float_get(op, "thresh"); + const float thresh_radians = thresh * (float)M_PI; + const int compare = BMO_slot_int_get(op, "compare"); + + /* initial_elem - other_elem */ + float delta_fl; + int delta_i; + + num_total = BM_mesh_elem_count(bm, BM_FACE); + + /* + * The first thing to do is to iterate through all the the selected items and mark them since + * they will be in the selection anyway. + * This will increase performance, (especially when the number of originally selected faces is high) + * so the overall complexity will be less than $O(mn)$ where is the total number of selected faces, + * and n is the total number of faces + */ + BMO_ITER (fs, &fs_iter, bm, op, "faces", BM_FACE) { + if (!BMO_elem_flag_test(bm, fs, FACE_MARK)) { /* is this really needed ? */ + BMO_elem_flag_enable(bm, fs, FACE_MARK); + num_sels++; + } + } + + /* allocate memory for the selected faces indices and for all temporary faces */ + indices = (int *)MEM_callocN(sizeof(int) * num_sels, "face indices util.c"); + f_ext = (SimSel_FaceExt *)MEM_callocN(sizeof(SimSel_FaceExt) * num_total, "f_ext util.c"); + + /* loop through all the faces and fill the faces/indices structure */ + BM_ITER_MESH (fm, &fm_iter, bm, BM_FACES_OF_MESH) { + f_ext[i].f = fm; + if (BMO_elem_flag_test(bm, fm, FACE_MARK)) { + indices[idx] = i; + idx++; + } + i++; + } + + /* + * Save us some computation burden: In case of perimeter/area/coplanar selection we compute + * only once. + */ + if (type == SIMFACE_PERIMETER || type == SIMFACE_AREA || type == SIMFACE_COPLANAR || type == SIMFACE_IMAGE) { + for (i = 0; i < num_total; i++) { + switch (type) { + case SIMFACE_PERIMETER: + /* set the perimeter */ + f_ext[i].perim = BM_face_calc_perimeter(f_ext[i].f); + break; + + case SIMFACE_COPLANAR: + /* compute the center of the polygon */ + BM_face_calc_center_mean(f_ext[i].f, f_ext[i].c); + + /* normalize the polygon normal */ + copy_v3_v3(t_no, f_ext[i].f->no); + normalize_v3(t_no); + + /* compute the plane distance */ + f_ext[i].d = dot_v3v3(t_no, f_ext[i].c); + break; + + case SIMFACE_AREA: + f_ext[i].area = BM_face_calc_area(f_ext[i].f); + break; + + case SIMFACE_IMAGE: + f_ext[i].t = NULL; + if (CustomData_has_layer(&(bm->pdata), CD_MTEXPOLY)) { + MTexPoly *mtpoly = CustomData_bmesh_get(&bm->pdata, f_ext[i].f->head.data, CD_MTEXPOLY); + f_ext[i].t = mtpoly->tpage; + } + break; + } + } + } + + /* now select the rest (if any) */ + for (i = 0; i < num_total; i++) { + fm = f_ext[i].f; + if (!BMO_elem_flag_test(bm, fm, FACE_MARK) && !BM_elem_flag_test(fm, BM_ELEM_HIDDEN)) { + int cont = TRUE; + for (idx = 0; idx < num_sels && cont == TRUE; idx++) { + fs = f_ext[indices[idx]].f; + switch (type) { + case SIMFACE_MATERIAL: + if (fm->mat_nr == fs->mat_nr) { + BMO_elem_flag_enable(bm, fm, FACE_MARK); + cont = FALSE; + } + break; + + case SIMFACE_IMAGE: + if (f_ext[i].t == f_ext[indices[idx]].t) { + BMO_elem_flag_enable(bm, fm, FACE_MARK); + cont = FALSE; + } + break; + + case SIMFACE_NORMAL: + angle = angle_normalized_v3v3(fs->no, fm->no); /* if the angle between the normals -> 0 */ + if (angle <= thresh_radians) { + BMO_elem_flag_enable(bm, fm, FACE_MARK); + cont = FALSE; + } + break; + + case SIMFACE_COPLANAR: + angle = angle_normalized_v3v3(fs->no, fm->no); /* angle -> 0 */ + if (angle <= thresh_radians) { /* and dot product difference -> 0 */ + delta_fl = f_ext[i].d - f_ext[indices[idx]].d; + if (bm_sel_similar_cmp_fl(delta_fl, thresh, compare)) { + BMO_elem_flag_enable(bm, fm, FACE_MARK); + cont = FALSE; + } + } + break; + + case SIMFACE_AREA: + delta_fl = f_ext[i].area - f_ext[indices[idx]].area; + if (bm_sel_similar_cmp_fl(delta_fl, thresh, compare)) { + BMO_elem_flag_enable(bm, fm, FACE_MARK); + cont = FALSE; + } + break; + + case SIMFACE_SIDES: + delta_i = fm->len - fs->len; + if (bm_sel_similar_cmp_i(delta_i, compare)) { + BMO_elem_flag_enable(bm, fm, FACE_MARK); + cont = FALSE; + } + break; + + case SIMFACE_PERIMETER: + delta_fl = f_ext[i].perim - f_ext[indices[idx]].perim; + if (bm_sel_similar_cmp_fl(delta_fl, thresh, compare)) { + BMO_elem_flag_enable(bm, fm, FACE_MARK); + cont = FALSE; + } + break; + default: + BLI_assert(0); + } + } + } + } + + MEM_freeN(f_ext); + MEM_freeN(indices); + + /* transfer all marked faces to the output slot */ + BMO_slot_buffer_from_enabled_flag(bm, op, "faceout", BM_FACE, FACE_MARK); +#undef FACE_MARK +} + +/**************************************************************************** * + * Similar Edges + **************************************************************************** */ + +/* + * extra edge information + */ +typedef struct SimSel_EdgeExt { + BMEdge *e; + union { + float dir[3]; + float angle; /* angle between the face */ + }; + + union { + float length; /* edge length */ + int faces; /* faces count */ + }; +} SimSel_EdgeExt; + +/* + * select similar edges: the choices are in the enum in source/blender/bmesh/bmesh_operators.h + * choices are length, direction, face, ... + */ +void bmo_similar_edges_exec(BMesh *bm, BMOperator *op) +{ +#define EDGE_MARK 1 + + BMOIter es_iter; /* selected edges iterator */ + BMIter e_iter; /* mesh edges iterator */ + BMEdge *es; /* selected edge */ + BMEdge *e; /* mesh edge */ + int idx = 0, i = 0 /* , f = 0 */; + int *indices = NULL; + SimSel_EdgeExt *e_ext = NULL; + // float *angles = NULL; + float angle; + + int num_sels = 0, num_total = 0; + const int type = BMO_slot_int_get(op, "type"); + const float thresh = BMO_slot_float_get(op, "thresh"); + const int compare = BMO_slot_int_get(op, "compare"); + + /* initial_elem - other_elem */ + float delta_fl; + int delta_i; + + /* sanity checks that the data we need is available */ + switch (type) { + case SIMEDGE_CREASE: + if (!CustomData_has_layer(&bm->edata, CD_CREASE)) { + return; + } + break; + case SIMEDGE_BEVEL: + if (!CustomData_has_layer(&bm->edata, CD_BWEIGHT)) { + return; + } + break; + } + + num_total = BM_mesh_elem_count(bm, BM_EDGE); + + /* iterate through all selected edges and mark them */ + BMO_ITER (es, &es_iter, bm, op, "edges", BM_EDGE) { + BMO_elem_flag_enable(bm, es, EDGE_MARK); + num_sels++; + } + + /* allocate memory for the selected edges indices and for all temporary edges */ + indices = (int *)MEM_callocN(sizeof(int) * num_sels, __func__); + e_ext = (SimSel_EdgeExt *)MEM_callocN(sizeof(SimSel_EdgeExt) * num_total, __func__); + + /* loop through all the edges and fill the edges/indices structure */ + BM_ITER_MESH (e, &e_iter, bm, BM_EDGES_OF_MESH) { + e_ext[i].e = e; + if (BMO_elem_flag_test(bm, e, EDGE_MARK)) { + indices[idx] = i; + idx++; + } + i++; + } + + /* save us some computation time by doing heavy computation once */ + if (type == SIMEDGE_LENGTH || type == SIMEDGE_FACE || type == SIMEDGE_DIR || type == SIMEDGE_FACE_ANGLE) { + for (i = 0; i < num_total; i++) { + switch (type) { + case SIMEDGE_LENGTH: /* compute the length of the edge */ + e_ext[i].length = len_v3v3(e_ext[i].e->v1->co, e_ext[i].e->v2->co); + break; + + case SIMEDGE_DIR: /* compute the direction */ + sub_v3_v3v3(e_ext[i].dir, e_ext[i].e->v1->co, e_ext[i].e->v2->co); + normalize_v3(e_ext[i].dir); + break; + + case SIMEDGE_FACE: /* count the faces around the edge */ + e_ext[i].faces = BM_edge_face_count(e_ext[i].e); + break; + + case SIMEDGE_FACE_ANGLE: + e_ext[i].faces = BM_edge_face_count(e_ext[i].e); + if (e_ext[i].faces == 2) + e_ext[i].angle = BM_edge_calc_face_angle(e_ext[i].e); + break; + } + } + } + + /* select the edges if any */ + for (i = 0; i < num_total; i++) { + e = e_ext[i].e; + if (!BMO_elem_flag_test(bm, e, EDGE_MARK) && !BM_elem_flag_test(e, BM_ELEM_HIDDEN)) { + int cont = TRUE; + for (idx = 0; idx < num_sels && cont == TRUE; idx++) { + es = e_ext[indices[idx]].e; + switch (type) { + case SIMEDGE_LENGTH: + delta_fl = e_ext[i].length - e_ext[indices[idx]].length; + if (bm_sel_similar_cmp_fl(delta_fl, thresh, compare)) { + BMO_elem_flag_enable(bm, e, EDGE_MARK); + cont = FALSE; + } + break; + + case SIMEDGE_DIR: + /* compute the angle between the two edges */ + angle = angle_normalized_v3v3(e_ext[i].dir, e_ext[indices[idx]].dir); + + if (angle > (float)(M_PI / 2.0)) /* use the smallest angle between the edges */ + angle = fabsf(angle - (float)M_PI); + + if (angle / (float)(M_PI / 2.0) <= thresh) { + BMO_elem_flag_enable(bm, e, EDGE_MARK); + cont = FALSE; + } + break; + + case SIMEDGE_FACE: + delta_i = e_ext[i].faces - e_ext[indices[idx]].faces; + if (bm_sel_similar_cmp_i(delta_i, compare)) { + BMO_elem_flag_enable(bm, e, EDGE_MARK); + cont = FALSE; + } + break; + + case SIMEDGE_FACE_ANGLE: + if (e_ext[i].faces == 2) { + if (e_ext[indices[idx]].faces == 2) { + if (fabsf(e_ext[i].angle - e_ext[indices[idx]].angle) <= thresh) { + BMO_elem_flag_enable(bm, e, EDGE_MARK); + cont = FALSE; + } + } + } + else { + cont = FALSE; + } + break; + + case SIMEDGE_CREASE: + { + float *c1, *c2; + + c1 = CustomData_bmesh_get(&bm->edata, e->head.data, CD_CREASE); + c2 = CustomData_bmesh_get(&bm->edata, es->head.data, CD_CREASE); + delta_fl = *c1 - *c2; + + if (bm_sel_similar_cmp_fl(delta_fl, thresh, compare)) { + BMO_elem_flag_enable(bm, e, EDGE_MARK); + cont = FALSE; + } + } + break; + + case SIMEDGE_BEVEL: + { + float *c1, *c2; + + c1 = CustomData_bmesh_get(&bm->edata, e->head.data, CD_BWEIGHT); + c2 = CustomData_bmesh_get(&bm->edata, es->head.data, CD_BWEIGHT); + delta_fl = *c1 - *c2; + + if (bm_sel_similar_cmp_fl(delta_fl, thresh, compare)) { + BMO_elem_flag_enable(bm, e, EDGE_MARK); + cont = FALSE; + } + } + break; + + case SIMEDGE_SEAM: + if (BM_elem_flag_test(e, BM_ELEM_SEAM) == BM_elem_flag_test(es, BM_ELEM_SEAM)) { + BMO_elem_flag_enable(bm, e, EDGE_MARK); + cont = FALSE; + } + break; + + case SIMEDGE_SHARP: + if (BM_elem_flag_test(e, BM_ELEM_SMOOTH) == BM_elem_flag_test(es, BM_ELEM_SMOOTH)) { + BMO_elem_flag_enable(bm, e, EDGE_MARK); + cont = FALSE; + } + break; + case SIMEDGE_FREESTYLE: + if (BM_elem_flag_test(e, BM_ELEM_FREESTYLE) == BM_elem_flag_test(es, BM_ELEM_FREESTYLE)) { + BMO_elem_flag_enable(bm, e, EDGE_MARK); + cont = 0; + } + break; + default: + BLI_assert(0); + } + } + } + } + + MEM_freeN(e_ext); + MEM_freeN(indices); + + /* transfer all marked edges to the output slot */ + BMO_slot_buffer_from_enabled_flag(bm, op, "edgeout", BM_EDGE, EDGE_MARK); + +#undef EDGE_MARK +} + +/**************************************************************************** * + * Similar Vertices + **************************************************************************** */ + +typedef struct SimSel_VertExt { + BMVert *v; + union { + int num_faces; /* adjacent faces */ + int num_edges; /* adjacent edges */ + MDeformVert *dvert; /* deform vertex */ + }; +} SimSel_VertExt; + +/* + * select similar vertices: the choices are in the enum in source/blender/bmesh/bmesh_operators.h + * choices are normal, face, vertex group... + */ +void bmo_similar_verts_exec(BMesh *bm, BMOperator *op) +{ +#define VERT_MARK 1 + + BMOIter vs_iter; /* selected verts iterator */ + BMIter v_iter; /* mesh verts iterator */ + BMVert *vs; /* selected vertex */ + BMVert *v; /* mesh vertex */ + SimSel_VertExt *v_ext = NULL; + int *indices = NULL; + int num_total = 0, num_sels = 0, i = 0, idx = 0; + const int type = BMO_slot_int_get(op, "type"); + const float thresh = BMO_slot_float_get(op, "thresh"); + const float thresh_radians = thresh * (float)M_PI; + const int compare = BMO_slot_int_get(op, "compare"); + + /* initial_elem - other_elem */ +// float delta_fl; + int delta_i; + + num_total = BM_mesh_elem_count(bm, BM_VERT); + + /* iterate through all selected edges and mark them */ + BMO_ITER (vs, &vs_iter, bm, op, "verts", BM_VERT) { + BMO_elem_flag_enable(bm, vs, VERT_MARK); + num_sels++; + } + + /* allocate memory for the selected vertices indices and for all temporary vertices */ + indices = (int *)MEM_mallocN(sizeof(int) * num_sels, "vertex indices"); + v_ext = (SimSel_VertExt *)MEM_mallocN(sizeof(SimSel_VertExt) * num_total, "vertex extra"); + + /* loop through all the vertices and fill the vertices/indices structure */ + BM_ITER_MESH (v, &v_iter, bm, BM_VERTS_OF_MESH) { + v_ext[i].v = v; + if (BMO_elem_flag_test(bm, v, VERT_MARK)) { + indices[idx] = i; + idx++; + } + + switch (type) { + case SIMVERT_FACE: + /* calling BM_vert_face_count every time is time consumming, so call it only once per vertex */ + v_ext[i].num_faces = BM_vert_face_count(v); + break; + + case SIMVERT_VGROUP: + if (CustomData_has_layer(&(bm->vdata), CD_MDEFORMVERT)) { + v_ext[i].dvert = CustomData_bmesh_get(&bm->vdata, v_ext[i].v->head.data, CD_MDEFORMVERT); + } + else { + v_ext[i].dvert = NULL; + } + break; + case SIMVERT_EDGE: + v_ext[i].num_edges = BM_vert_edge_count(v); + break; + } + + i++; + } + + /* select the vertices if any */ + for (i = 0; i < num_total; i++) { + v = v_ext[i].v; + if (!BMO_elem_flag_test(bm, v, VERT_MARK) && !BM_elem_flag_test(v, BM_ELEM_HIDDEN)) { + int cont = TRUE; + for (idx = 0; idx < num_sels && cont == TRUE; idx++) { + vs = v_ext[indices[idx]].v; + switch (type) { + case SIMVERT_NORMAL: + /* compare the angle between the normals */ + if (angle_normalized_v3v3(v->no, vs->no) <= thresh_radians) { + BMO_elem_flag_enable(bm, v, VERT_MARK); + cont = FALSE; + } + break; + case SIMVERT_FACE: + /* number of adjacent faces */ + delta_i = v_ext[i].num_faces - v_ext[indices[idx]].num_faces; + if (bm_sel_similar_cmp_i(delta_i, compare)) { + BMO_elem_flag_enable(bm, v, VERT_MARK); + cont = FALSE; + } + break; + + case SIMVERT_VGROUP: + if (v_ext[i].dvert != NULL && v_ext[indices[idx]].dvert != NULL) { + if (defvert_find_shared(v_ext[i].dvert, v_ext[indices[idx]].dvert) != -1) { + BMO_elem_flag_enable(bm, v, VERT_MARK); + cont = FALSE; + } + } + break; + case SIMVERT_EDGE: + /* number of adjacent edges */ + delta_i = v_ext[i].num_edges - v_ext[indices[idx]].num_edges; + if (bm_sel_similar_cmp_i(delta_i, compare)) { + BMO_elem_flag_enable(bm, v, VERT_MARK); + cont = FALSE; + } + break; + default: + BLI_assert(0); + } + } + } + } + + MEM_freeN(indices); + MEM_freeN(v_ext); + + BMO_slot_buffer_from_enabled_flag(bm, op, "vertout", BM_VERT, VERT_MARK); + +#undef VERT_MARK +} diff --git a/source/blender/bmesh/operators/bmo_smooth_laplacian.c b/source/blender/bmesh/operators/bmo_smooth_laplacian.c index 9a2a9c022e6..51b9adb5de3 100644 --- a/source/blender/bmesh/operators/bmo_smooth_laplacian.c +++ b/source/blender/bmesh/operators/bmo_smooth_laplacian.c @@ -45,19 +45,19 @@ #define SMOOTH_LAPLACIAN_AREA_FACTOR 4.0f #define SMOOTH_LAPLACIAN_EDGE_FACTOR 2.0f -#define SMOOTH_LAPLACIAN_MAX_EDGE_PERCENTAGE 1.8 -#define SMOOTH_LAPLACIAN_MIN_EDGE_PERCENTAGE 0.15 +#define SMOOTH_LAPLACIAN_MAX_EDGE_PERCENTAGE 1.8f +#define SMOOTH_LAPLACIAN_MIN_EDGE_PERCENTAGE 0.15f struct BLaplacianSystem { - float *eweights; /* Length weights per Edge */ + float *eweights; /* Length weights per Edge */ float (*fweights)[3]; /* Cotangent weights per face */ - float *ring_areas; /* Total area per ring*/ - float *vlengths; /* Total sum of lengths(edges) per vertice*/ - float *vweights; /* Total sum of weights per vertice*/ - int numEdges; /* Number of edges*/ - int numFaces; /* Number of faces*/ - int numVerts; /* Number of verts*/ - short *zerola; /* Is zero area or length*/ + float *ring_areas; /* Total area per ring*/ + float *vlengths; /* Total sum of lengths(edges) per vertice*/ + float *vweights; /* Total sum of weights per vertice*/ + int numEdges; /* Number of edges*/ + int numFaces; /* Number of faces*/ + int numVerts; /* Number of verts*/ + short *zerola; /* Is zero area or length*/ /* Pointers to data*/ BMesh *bm; @@ -72,13 +72,13 @@ typedef struct BLaplacianSystem LaplacianSystem; static float compute_volume(BMesh *bm); static float cotan_weight(float *v1, float *v2, float *v3); static int vert_is_boundary(BMVert *v); -static LaplacianSystem * init_laplacian_system( int a_numEdges, int a_numFaces, int a_numVerts); -static void init_laplacian_matrix(LaplacianSystem * sys); -static void delete_laplacian_system(LaplacianSystem * sys); +static LaplacianSystem *init_laplacian_system(int a_numEdges, int a_numFaces, int a_numVerts); +static void init_laplacian_matrix(LaplacianSystem *sys); +static void delete_laplacian_system(LaplacianSystem *sys); static void delete_void_pointer(void *data); -static void fill_laplacian_matrix(LaplacianSystem * sys); +static void fill_laplacian_matrix(LaplacianSystem *sys); static void memset_laplacian_system(LaplacianSystem *sys, int val); -static void validate_solution(LaplacianSystem * sys, int usex, int usey, int usez, int volumepreservation); +static void validate_solution(LaplacianSystem *sys, int usex, int usey, int usez, int volumepreservation); static void volume_preservation(BMesh *bm, BMOperator *op, float vini, float vend, int usex, int usey, int usez); static void delete_void_pointer(void *data) @@ -89,7 +89,7 @@ static void delete_void_pointer(void *data) } } -static void delete_laplacian_system(LaplacianSystem * sys) +static void delete_laplacian_system(LaplacianSystem *sys) { delete_void_pointer(sys->eweights); delete_void_pointer(sys->fweights); @@ -107,17 +107,17 @@ static void delete_laplacian_system(LaplacianSystem * sys) static void memset_laplacian_system(LaplacianSystem *sys, int val) { - memset(sys->eweights , val, sizeof(float) * sys->numEdges); - memset(sys->fweights , val, sizeof(float) * sys->numFaces * 3); - memset(sys->ring_areas , val, sizeof(float) * sys->numVerts); - memset(sys->vlengths , val, sizeof(float) * sys->numVerts); - memset(sys->vweights , val, sizeof(float) * sys->numVerts); - memset(sys->zerola , val, sizeof(short) * sys->numVerts); + memset(sys->eweights, val, sizeof(float) * sys->numEdges); + memset(sys->fweights, val, sizeof(float) * sys->numFaces * 3); + memset(sys->ring_areas, val, sizeof(float) * sys->numVerts); + memset(sys->vlengths, val, sizeof(float) * sys->numVerts); + memset(sys->vweights, val, sizeof(float) * sys->numVerts); + memset(sys->zerola, val, sizeof(short) * sys->numVerts); } -static LaplacianSystem * init_laplacian_system( int a_numEdges, int a_numFaces, int a_numVerts) +static LaplacianSystem *init_laplacian_system(int a_numEdges, int a_numFaces, int a_numVerts) { - LaplacianSystem * sys; + LaplacianSystem *sys; sys = MEM_callocN(sizeof(LaplacianSystem), "ModLaplSmoothSystem"); sys->numEdges = a_numEdges; sys->numFaces = a_numFaces; @@ -128,19 +128,19 @@ static LaplacianSystem * init_laplacian_system( int a_numEdges, int a_numFaces, delete_laplacian_system(sys); return NULL; } - + sys->fweights = MEM_callocN(sizeof(float) * 3 * sys->numFaces, "ModLaplSmoothFWeight"); if (!sys->fweights) { delete_laplacian_system(sys); return NULL; } - + sys->ring_areas = MEM_callocN(sizeof(float) * sys->numVerts, "ModLaplSmoothRingAreas"); if (!sys->ring_areas) { delete_laplacian_system(sys); return NULL; } - + sys->vlengths = MEM_callocN(sizeof(float) * sys->numVerts, "ModLaplSmoothVlengths"); if (!sys->vlengths) { delete_laplacian_system(sys); @@ -163,7 +163,7 @@ static LaplacianSystem * init_laplacian_system( int a_numEdges, int a_numFaces, } /* Compute weigth between vertice v_i and all your neighbors - * weight between v_i and v_neighbor + * weight between v_i and v_neighbor * Wij = cot(alpha) + cot(beta) / (4.0 * total area of all faces * sum all weight) * v_i * * / | \ @@ -172,15 +172,15 @@ static LaplacianSystem * init_laplacian_system( int a_numEdges, int a_numFaces, * \ | / * \ | / * * v_neighbor -*/ + */ -static void init_laplacian_matrix(LaplacianSystem * sys) +static void init_laplacian_matrix(LaplacianSystem *sys) { float areaf; float *v1, *v2, *v3, *v4; float w1, w2, w3, w4; int i, j; - int has_4_vert ; + int has_4_vert; unsigned int idv1, idv2, idv3, idv4, idv[4]; BMEdge *e; BMFace *f; @@ -196,7 +196,7 @@ static void init_laplacian_matrix(LaplacianSystem * sys) v2 = e->v2->co; idv1 = BM_elem_index_get(e->v1); idv2 = BM_elem_index_get(e->v2); - + w1 = len_v3v3(v1, v2); if (w1 > sys->min_area) { w1 = 1.0f / w1; @@ -204,7 +204,8 @@ static void init_laplacian_matrix(LaplacianSystem * sys) sys->eweights[i] = w1; sys->vlengths[idv1] += w1; sys->vlengths[idv2] += w1; - }else{ + } + else { sys->zerola[idv1] = 1; sys->zerola[idv2] = 1; } @@ -235,7 +236,7 @@ static void init_laplacian_matrix(LaplacianSystem * sys) areaf = area_tri_v3(v1, v2, v3); } - if (fabs(areaf) < sys->min_area) { + if (fabsf(areaf) < sys->min_area) { sys->zerola[idv1] = 1; sys->zerola[idv2] = 1; sys->zerola[idv3] = 1; @@ -248,7 +249,7 @@ static void init_laplacian_matrix(LaplacianSystem * sys) if (has_4_vert) sys->ring_areas[idv4] += areaf; if (has_4_vert) { - + idv[0] = idv1; idv[1] = idv2; idv[2] = idv3; @@ -268,7 +269,7 @@ static void init_laplacian_matrix(LaplacianSystem * sys) w2 = cotan_weight(v4, v1, v2) + cotan_weight(v3, v1, v2); w3 = cotan_weight(v2, v3, v1) + cotan_weight(v4, v1, v3); w4 = cotan_weight(v2, v4, v1) + cotan_weight(v3, v4, v1); - + sys->vweights[idv1] += (w2 + w3 + w4) / 4.0f; } } @@ -282,7 +283,7 @@ static void init_laplacian_matrix(LaplacianSystem * sys) sys->fweights[i][0] += w1; sys->fweights[i][1] += w2; sys->fweights[i][2] += w3; - + sys->vweights[idv1] += w2 + w3; sys->vweights[idv2] += w1 + w3; sys->vweights[idv3] += w1 + w2; @@ -291,12 +292,12 @@ static void init_laplacian_matrix(LaplacianSystem * sys) } } -static void fill_laplacian_matrix(LaplacianSystem * sys) +static void fill_laplacian_matrix(LaplacianSystem *sys) { float *v1, *v2, *v3, *v4; float w2, w3, w4; int i, j; - int has_4_vert ; + int has_4_vert; unsigned int idv1, idv2, idv3, idv4, idv[4]; BMEdge *e; @@ -336,8 +337,8 @@ static void fill_laplacian_matrix(LaplacianSystem * sys) w2 = w2 / 4.0f; w3 = w3 / 4.0f; w4 = w4 / 4.0f; - - if (!vert_is_boundary(vf[j]) && sys->zerola[idv1] == 0) { + + if (!vert_is_boundary(vf[j]) && sys->zerola[idv1] == 0) { nlMatrixAdd(idv1, idv2, w2 * sys->vweights[idv1]); nlMatrixAdd(idv1, idv3, w3 * sys->vweights[idv1]); nlMatrixAdd(idv1, idv4, w4 * sys->vweights[idv1]); @@ -350,15 +351,15 @@ static void fill_laplacian_matrix(LaplacianSystem * sys) idv3 = BM_elem_index_get(vf[2]); /* Is ring if number of faces == number of edges around vertice*/ i = BM_elem_index_get(f); - if (!vert_is_boundary(vf[0]) && sys->zerola[idv1] == 0) { + if (!vert_is_boundary(vf[0]) && sys->zerola[idv1] == 0) { nlMatrixAdd(idv1, idv2, sys->fweights[i][2] * sys->vweights[idv1]); nlMatrixAdd(idv1, idv3, sys->fweights[i][1] * sys->vweights[idv1]); } - if (!vert_is_boundary(vf[1]) && sys->zerola[idv2] == 0) { + if (!vert_is_boundary(vf[1]) && sys->zerola[idv2] == 0) { nlMatrixAdd(idv2, idv1, sys->fweights[i][2] * sys->vweights[idv2]); nlMatrixAdd(idv2, idv3, sys->fweights[i][0] * sys->vweights[idv2]); } - if (!vert_is_boundary(vf[2]) && sys->zerola[idv3] == 0) { + if (!vert_is_boundary(vf[2]) && sys->zerola[idv3] == 0) { nlMatrixAdd(idv3, idv1, sys->fweights[i][1] * sys->vweights[idv3]); nlMatrixAdd(idv3, idv2, sys->fweights[i][0] * sys->vweights[idv3]); } @@ -392,7 +393,7 @@ static float cotan_weight(float *v1, float *v2, float *v3) if (clen == 0.0f) return 0.0f; - + return dot_v3v3(a, b) / clen; } @@ -402,7 +403,7 @@ static int vert_is_boundary(BMVert *v) BMFace *f; BMIter ei; BMIter fi; - BM_ITER_ELEM(ed, &ei, v, BM_EDGES_OF_VERT) { + BM_ITER_ELEM (ed, &ei, v, BM_EDGES_OF_VERT) { if (BM_edge_is_boundary(ed)) { return 1; } @@ -425,7 +426,7 @@ static float compute_volume(BMesh *bm) BMIter vi; BMVert *vn; BMVert *vf[4]; - + BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) { BM_ITER_ELEM_INDEX (vn, &vi, f, BM_VERTS_OF_FACE, i) { vf[i] = vn; @@ -442,13 +443,13 @@ static float compute_volume(BMesh *bm) y3 = vf[2]->co[1]; z3 = vf[2]->co[2]; - vol += (1.0 / 6.0) * (0.0 - x3*y2*z1 + x2*y3*z1 + x3*y1*z2 - x1*y3*z2 - x2*y1*z3 + x1*y2*z3); + vol += (1.0f / 6.0f) * (0.0f - x3 * y2 * z1 + x2 * y3 * z1 + x3 * y1 * z2 - x1 * y3 * z2 - x2 * y1 * z3 + x1 * y2 * z3); if (i == 4) { x4 = vf[3]->co[0]; y4 = vf[3]->co[1]; z4 = vf[3]->co[2]; - vol += (1.0 / 6.0) * (x1*y3*z4 - x1*y4*z3 - x3*y1*z4 + x3*z1*y4 + y1*x4*z3 - x4*y3*z1); + vol += (1.0f / 6.0f) * (x1 * y3 * z4 - x1 * y4 * z3 - x3 * y1 * z4 + x3 * z1 * y4 + y1 * x4 * z3 - x4 * y3 * z1); } } return fabs(vol); @@ -460,8 +461,8 @@ static void volume_preservation(BMesh *bm, BMOperator *op, float vini, float ven BMOIter siter; BMVert *v; - if (vend != 0.0f) { - beta = pow (vini / vend, 1.0f / 3.0f); + if (vend != 0.0f) { + beta = pow(vini / vend, 1.0f / 3.0f); BMO_ITER (v, &siter, bm, op, "verts", BM_VERT) { if (usex) { v->co[0] *= beta; @@ -472,12 +473,12 @@ static void volume_preservation(BMesh *bm, BMOperator *op, float vini, float ven if (usez) { v->co[2] *= beta; } - + } } } -static void validate_solution(LaplacianSystem * sys, int usex, int usey, int usez, int volumepreservation) +static void validate_solution(LaplacianSystem *sys, int usex, int usey, int usez, int volumepreservation) { int m_vertex_id; float leni, lene; @@ -502,7 +503,7 @@ static void validate_solution(LaplacianSystem * sys, int usex, int usey, int use ve2[2] = nlGetVariable(2, idv2); leni = len_v3v3(vi1, vi2); lene = len_v3v3(ve1, ve2); - if ( lene > leni* SMOOTH_LAPLACIAN_MAX_EDGE_PERCENTAGE || lene < leni*SMOOTH_LAPLACIAN_MIN_EDGE_PERCENTAGE) { + if (lene > leni * SMOOTH_LAPLACIAN_MAX_EDGE_PERCENTAGE || lene < leni * SMOOTH_LAPLACIAN_MIN_EDGE_PERCENTAGE) { sys->zerola[idv1] = 1; sys->zerola[idv2] = 1; } @@ -541,7 +542,7 @@ void bmo_smooth_laplacian_vert_exec(BMesh *bm, BMOperator *op) float w; BMOIter siter; BMVert *v; - LaplacianSystem * sys; + LaplacianSystem *sys; sys = init_laplacian_system(bm->totedge, bm->totface, bm->totvert); if (!sys) return; @@ -568,16 +569,16 @@ void bmo_smooth_laplacian_vert_exec(BMesh *bm, BMOperator *op) nlSolverParameteri(NL_NB_ROWS, bm->totvert); nlSolverParameteri(NL_NB_RIGHT_HAND_SIDES, 3); - nlBegin(NL_SYSTEM); - for (i=0; i < bm->totvert; i++) { + nlBegin(NL_SYSTEM); + for (i = 0; i < bm->totvert; i++) { nlLockVariable(i); } BMO_ITER (v, &siter, bm, op, "verts", BM_VERT) { m_vertex_id = BM_elem_index_get(v); nlUnlockVariable(m_vertex_id); - nlSetVariable(0,m_vertex_id, v->co[0]); - nlSetVariable(1,m_vertex_id, v->co[1]); - nlSetVariable(2,m_vertex_id, v->co[2]); + nlSetVariable(0, m_vertex_id, v->co[0]); + nlSetVariable(1, m_vertex_id, v->co[1]); + nlSetVariable(2, m_vertex_id, v->co[2]); } nlBegin(NL_MATRIX); @@ -594,7 +595,7 @@ void bmo_smooth_laplacian_vert_exec(BMesh *bm, BMOperator *op) w = sys->vlengths[i]; sys->vlengths[i] = (w == 0.0f) ? 0.0f : -lambda_border * 2.0f / w; - if (!vert_is_boundary(v)) { + if (!vert_is_boundary(v)) { nlMatrixAdd(i, i, 1.0f + lambda / (4.0f * sys->ring_areas[i])); } else { @@ -603,16 +604,16 @@ void bmo_smooth_laplacian_vert_exec(BMesh *bm, BMOperator *op) } else { nlMatrixAdd(i, i, 1.0f); - } + } } fill_laplacian_matrix(sys); - + nlEnd(NL_MATRIX); nlEnd(NL_SYSTEM); if (nlSolveAdvanced(NULL, NL_TRUE) ) { validate_solution(sys, usex, usey, usez, volumepreservation); } - + delete_laplacian_system(sys); } diff --git a/source/blender/bmesh/operators/bmo_subdivide.c b/source/blender/bmesh/operators/bmo_subdivide.c index c6726ec6f3e..346daf830d0 100644 --- a/source/blender/bmesh/operators/bmo_subdivide.c +++ b/source/blender/bmesh/operators/bmo_subdivide.c @@ -54,7 +54,7 @@ #define ELE_SPLIT 16 /* see bug [#32665], 0.00005 means a we get face splits at a little under 1.0 degrees */ -#define FLT_FACE_SPLIT_EPSILON 0.00005 +#define FLT_FACE_SPLIT_EPSILON 0.00005f /* * NOTE: beauty has been renamed to flag! diff --git a/source/blender/bmesh/operators/bmo_utils.c b/source/blender/bmesh/operators/bmo_utils.c index b396da3b8d1..e311b383b86 100644 --- a/source/blender/bmesh/operators/bmo_utils.c +++ b/source/blender/bmesh/operators/bmo_utils.c @@ -479,554 +479,6 @@ void bmo_smooth_vert_exec(BMesh *bm, BMOperator *op) BLI_array_free(cos); } -/* - * compute the fake surface of an ngon - * This is done by decomposing the ngon into triangles who share the centroid of the ngon - * while this method is far from being exact, it should guarantee an invariance. - * - * NOTE: This should probably go to bmesh_polygon.c - */ -static float ngon_fake_area(BMFace *f) -{ - BMIter liter; - BMLoop *l; - int num_verts = 0; - float v[3], sv[3], c[3]; - float area = 0.0f; - - BM_face_calc_center_mean(f, c); - - BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) { - if (num_verts == 0) { - copy_v3_v3(v, l->v->co); - copy_v3_v3(sv, l->v->co); - num_verts++; - } - else { - area += area_tri_v3(v, c, l->v->co); - copy_v3_v3(v, l->v->co); - num_verts++; - } - } - - area += area_tri_v3(v, c, sv); - - return area; -} - -/* - * extra face data (computed data) - */ -typedef struct SimSel_FaceExt { - BMFace *f; /* the face */ - float c[3]; /* center */ - union { - float area; /* area */ - float perim; /* perimeter */ - float d; /* 4th component of plane (the first three being the normal) */ - struct Image *t; /* image pointer */ - }; -} SimSel_FaceExt; - -/* - * Select similar faces, the choices are in the enum in source/blender/bmesh/bmesh_operators.h - * We select either similar faces based on material, image, area, perimeter, normal, or the coplanar faces - */ -void bmo_similar_faces_exec(BMesh *bm, BMOperator *op) -{ - BMIter fm_iter; - BMFace *fs, *fm; - BMOIter fs_iter; - int num_sels = 0, num_total = 0, i = 0, idx = 0; - float angle = 0.0f; - SimSel_FaceExt *f_ext = NULL; - int *indices = NULL; - float t_no[3]; /* temporary normal */ - int type = BMO_slot_int_get(op, "type"); - const float thresh = BMO_slot_float_get(op, "thresh"); - const float thresh_radians = thresh * (float)M_PI; - - num_total = BM_mesh_elem_count(bm, BM_FACE); - - /* - * The first thing to do is to iterate through all the the selected items and mark them since - * they will be in the selection anyway. - * This will increase performance, (especially when the number of originally selected faces is high) - * so the overall complexity will be less than $O(mn)$ where is the total number of selected faces, - * and n is the total number of faces - */ - BMO_ITER (fs, &fs_iter, bm, op, "faces", BM_FACE) { - if (!BMO_elem_flag_test(bm, fs, FACE_MARK)) { /* is this really needed ? */ - BMO_elem_flag_enable(bm, fs, FACE_MARK); - num_sels++; - } - } - - /* allocate memory for the selected faces indices and for all temporary faces */ - indices = (int *)MEM_callocN(sizeof(int) * num_sels, "face indices util.c"); - f_ext = (SimSel_FaceExt *)MEM_callocN(sizeof(SimSel_FaceExt) * num_total, "f_ext util.c"); - - /* loop through all the faces and fill the faces/indices structure */ - BM_ITER_MESH (fm, &fm_iter, bm, BM_FACES_OF_MESH) { - f_ext[i].f = fm; - if (BMO_elem_flag_test(bm, fm, FACE_MARK)) { - indices[idx] = i; - idx++; - } - i++; - } - - /* - * Save us some computation burden: In case of perimeter/area/coplanar selection we compute - * only once. - */ - if (type == SIMFACE_PERIMETER || type == SIMFACE_AREA || type == SIMFACE_COPLANAR || type == SIMFACE_IMAGE) { - for (i = 0; i < num_total; i++) { - switch (type) { - case SIMFACE_PERIMETER: - /* set the perimeter */ - f_ext[i].perim = BM_face_calc_perimeter(f_ext[i].f); - break; - - case SIMFACE_COPLANAR: - /* compute the center of the polygon */ - BM_face_calc_center_mean(f_ext[i].f, f_ext[i].c); - - /* normalize the polygon normal */ - copy_v3_v3(t_no, f_ext[i].f->no); - normalize_v3(t_no); - - /* compute the plane distance */ - f_ext[i].d = dot_v3v3(t_no, f_ext[i].c); - break; - - case SIMFACE_AREA: - f_ext[i].area = ngon_fake_area(f_ext[i].f); - break; - - case SIMFACE_IMAGE: - f_ext[i].t = NULL; - if (CustomData_has_layer(&(bm->pdata), CD_MTEXPOLY)) { - MTexPoly *mtpoly = CustomData_bmesh_get(&bm->pdata, f_ext[i].f->head.data, CD_MTEXPOLY); - f_ext[i].t = mtpoly->tpage; - } - break; - } - } - } - - /* now select the rest (if any) */ - for (i = 0; i < num_total; i++) { - fm = f_ext[i].f; - if (!BMO_elem_flag_test(bm, fm, FACE_MARK) && !BM_elem_flag_test(fm, BM_ELEM_HIDDEN)) { - int cont = TRUE; - for (idx = 0; idx < num_sels && cont == TRUE; idx++) { - fs = f_ext[indices[idx]].f; - switch (type) { - case SIMFACE_MATERIAL: - if (fm->mat_nr == fs->mat_nr) { - BMO_elem_flag_enable(bm, fm, FACE_MARK); - cont = FALSE; - } - break; - - case SIMFACE_IMAGE: - if (f_ext[i].t == f_ext[indices[idx]].t) { - BMO_elem_flag_enable(bm, fm, FACE_MARK); - cont = FALSE; - } - break; - - case SIMFACE_NORMAL: - angle = angle_normalized_v3v3(fs->no, fm->no); /* if the angle between the normals -> 0 */ - if (angle <= thresh_radians) { - BMO_elem_flag_enable(bm, fm, FACE_MARK); - cont = FALSE; - } - break; - - case SIMFACE_COPLANAR: - angle = angle_normalized_v3v3(fs->no, fm->no); /* angle -> 0 */ - if (angle <= thresh_radians) { /* and dot product difference -> 0 */ - if (fabsf(f_ext[i].d - f_ext[indices[idx]].d) <= thresh) { - BMO_elem_flag_enable(bm, fm, FACE_MARK); - cont = FALSE; - } - } - break; - - case SIMFACE_AREA: - if (fabsf(f_ext[i].area - f_ext[indices[idx]].area) <= thresh) { - BMO_elem_flag_enable(bm, fm, FACE_MARK); - cont = FALSE; - } - break; - - case SIMFACE_PERIMETER: - if (fabsf(f_ext[i].perim - f_ext[indices[idx]].perim) <= thresh) { - BMO_elem_flag_enable(bm, fm, FACE_MARK); - cont = FALSE; - } - break; - - case SIMFACE_FREESTYLE: - if (BM_elem_flag_test(fm, BM_ELEM_FREESTYLE) == BM_elem_flag_test(fs, BM_ELEM_FREESTYLE)) { - BMO_elem_flag_enable(bm, fm, FACE_MARK); - cont = 0; - } - break; - } - } - } - } - - MEM_freeN(f_ext); - MEM_freeN(indices); - - /* transfer all marked faces to the output slot */ - BMO_slot_buffer_from_enabled_flag(bm, op, "faceout", BM_FACE, FACE_MARK); -} - -/**************************************************************************** * - * Similar Edges - **************************************************************************** */ -#define EDGE_MARK 1 - -/* - * extra edge information - */ -typedef struct SimSel_EdgeExt { - BMEdge *e; - union { - float dir[3]; - float angle; /* angle between the face */ - }; - - union { - float length; /* edge length */ - int faces; /* faces count */ - }; -} SimSel_EdgeExt; - -/* - * select similar edges: the choices are in the enum in source/blender/bmesh/bmesh_operators.h - * choices are length, direction, face, ... - */ -void bmo_similar_edges_exec(BMesh *bm, BMOperator *op) -{ - BMOIter es_iter; /* selected edges iterator */ - BMIter e_iter; /* mesh edges iterator */ - BMEdge *es; /* selected edge */ - BMEdge *e; /* mesh edge */ - int idx = 0, i = 0 /* , f = 0 */; - int *indices = NULL; - SimSel_EdgeExt *e_ext = NULL; - // float *angles = NULL; - float angle; - - int num_sels = 0, num_total = 0; - int type = BMO_slot_int_get(op, "type"); - const float thresh = BMO_slot_float_get(op, "thresh"); - - /* sanity checks that the data we need is available */ - switch (type) { - case SIMEDGE_CREASE: - if (!CustomData_has_layer(&bm->edata, CD_CREASE)) { - return; - } - break; - case SIMEDGE_BEVEL: - if (!CustomData_has_layer(&bm->edata, CD_BWEIGHT)) { - return; - } - break; - } - - num_total = BM_mesh_elem_count(bm, BM_EDGE); - - /* iterate through all selected edges and mark them */ - BMO_ITER (es, &es_iter, bm, op, "edges", BM_EDGE) { - BMO_elem_flag_enable(bm, es, EDGE_MARK); - num_sels++; - } - - /* allocate memory for the selected edges indices and for all temporary edges */ - indices = (int *)MEM_callocN(sizeof(int) * num_sels, __func__); - e_ext = (SimSel_EdgeExt *)MEM_callocN(sizeof(SimSel_EdgeExt) * num_total, __func__); - - /* loop through all the edges and fill the edges/indices structure */ - BM_ITER_MESH (e, &e_iter, bm, BM_EDGES_OF_MESH) { - e_ext[i].e = e; - if (BMO_elem_flag_test(bm, e, EDGE_MARK)) { - indices[idx] = i; - idx++; - } - i++; - } - - /* save us some computation time by doing heavy computation once */ - if (type == SIMEDGE_LENGTH || type == SIMEDGE_FACE || type == SIMEDGE_DIR || type == SIMEDGE_FACE_ANGLE) { - for (i = 0; i < num_total; i++) { - switch (type) { - case SIMEDGE_LENGTH: /* compute the length of the edge */ - e_ext[i].length = len_v3v3(e_ext[i].e->v1->co, e_ext[i].e->v2->co); - break; - - case SIMEDGE_DIR: /* compute the direction */ - sub_v3_v3v3(e_ext[i].dir, e_ext[i].e->v1->co, e_ext[i].e->v2->co); - normalize_v3(e_ext[i].dir); - break; - - case SIMEDGE_FACE: /* count the faces around the edge */ - e_ext[i].faces = BM_edge_face_count(e_ext[i].e); - break; - - case SIMEDGE_FACE_ANGLE: - e_ext[i].faces = BM_edge_face_count(e_ext[i].e); - if (e_ext[i].faces == 2) - e_ext[i].angle = BM_edge_calc_face_angle(e_ext[i].e); - break; - } - } - } - - /* select the edges if any */ - for (i = 0; i < num_total; i++) { - e = e_ext[i].e; - if (!BMO_elem_flag_test(bm, e, EDGE_MARK) && !BM_elem_flag_test(e, BM_ELEM_HIDDEN)) { - int cont = TRUE; - for (idx = 0; idx < num_sels && cont == TRUE; idx++) { - es = e_ext[indices[idx]].e; - switch (type) { - case SIMEDGE_LENGTH: - if (fabsf(e_ext[i].length - e_ext[indices[idx]].length) <= thresh) { - BMO_elem_flag_enable(bm, e, EDGE_MARK); - cont = FALSE; - } - break; - - case SIMEDGE_DIR: - /* compute the angle between the two edges */ - angle = angle_normalized_v3v3(e_ext[i].dir, e_ext[indices[idx]].dir); - - if (angle > (float)(M_PI / 2.0)) /* use the smallest angle between the edges */ - angle = fabsf(angle - (float)M_PI); - - if (angle / (float)(M_PI / 2.0) <= thresh) { - BMO_elem_flag_enable(bm, e, EDGE_MARK); - cont = FALSE; - } - break; - - case SIMEDGE_FACE: - if (e_ext[i].faces == e_ext[indices[idx]].faces) { - BMO_elem_flag_enable(bm, e, EDGE_MARK); - cont = FALSE; - } - break; - - case SIMEDGE_FACE_ANGLE: - if (e_ext[i].faces == 2) { - if (e_ext[indices[idx]].faces == 2) { - if (fabsf(e_ext[i].angle - e_ext[indices[idx]].angle) <= thresh) { - BMO_elem_flag_enable(bm, e, EDGE_MARK); - cont = FALSE; - } - } - } - else { - cont = FALSE; - } - break; - - case SIMEDGE_CREASE: - { - float *c1, *c2; - - c1 = CustomData_bmesh_get(&bm->edata, e->head.data, CD_CREASE); - c2 = CustomData_bmesh_get(&bm->edata, es->head.data, CD_CREASE); - - if (fabsf(*c1 - *c2) <= thresh) { - BMO_elem_flag_enable(bm, e, EDGE_MARK); - cont = FALSE; - } - } - break; - - case SIMEDGE_BEVEL: - { - float *c1, *c2; - - c1 = CustomData_bmesh_get(&bm->edata, e->head.data, CD_BWEIGHT); - c2 = CustomData_bmesh_get(&bm->edata, es->head.data, CD_BWEIGHT); - - if (fabsf(*c1 - *c2) <= thresh) { - BMO_elem_flag_enable(bm, e, EDGE_MARK); - cont = FALSE; - } - } - break; - - case SIMEDGE_SEAM: - if (BM_elem_flag_test(e, BM_ELEM_SEAM) == BM_elem_flag_test(es, BM_ELEM_SEAM)) { - BMO_elem_flag_enable(bm, e, EDGE_MARK); - cont = FALSE; - } - break; - - case SIMEDGE_SHARP: - if (BM_elem_flag_test(e, BM_ELEM_SMOOTH) == BM_elem_flag_test(es, BM_ELEM_SMOOTH)) { - BMO_elem_flag_enable(bm, e, EDGE_MARK); - cont = FALSE; - } - break; - - case SIMEDGE_FREESTYLE: - if (BM_elem_flag_test(e, BM_ELEM_FREESTYLE) == BM_elem_flag_test(es, BM_ELEM_FREESTYLE)) { - BMO_elem_flag_enable(bm, e, EDGE_MARK); - cont = 0; - } - break; - } - } - } - } - - MEM_freeN(e_ext); - MEM_freeN(indices); - - /* transfer all marked edges to the output slot */ - BMO_slot_buffer_from_enabled_flag(bm, op, "edgeout", BM_EDGE, EDGE_MARK); -} - -/**************************************************************************** * - * Similar Vertices - **************************************************************************** */ -#define VERT_MARK 1 - -typedef struct SimSel_VertExt { - BMVert *v; - union { - int num_faces; /* adjacent faces */ - int num_edges; /* adjacent edges */ - MDeformVert *dvert; /* deform vertex */ - }; -} SimSel_VertExt; - -/* - * select similar vertices: the choices are in the enum in source/blender/bmesh/bmesh_operators.h - * choices are normal, face, vertex group... - */ -void bmo_similar_verts_exec(BMesh *bm, BMOperator *op) -{ - BMOIter vs_iter; /* selected verts iterator */ - BMIter v_iter; /* mesh verts iterator */ - BMVert *vs; /* selected vertex */ - BMVert *v; /* mesh vertex */ - SimSel_VertExt *v_ext = NULL; - int *indices = NULL; - int num_total = 0, num_sels = 0, i = 0, idx = 0; - int type = BMO_slot_int_get(op, "type"); - const float thresh = BMO_slot_float_get(op, "thresh"); - const float thresh_radians = thresh * (float)M_PI; - - num_total = BM_mesh_elem_count(bm, BM_VERT); - - /* iterate through all selected edges and mark them */ - BMO_ITER (vs, &vs_iter, bm, op, "verts", BM_VERT) { - BMO_elem_flag_enable(bm, vs, VERT_MARK); - num_sels++; - } - - /* allocate memory for the selected vertices indices and for all temporary vertices */ - indices = (int *)MEM_mallocN(sizeof(int) * num_sels, "vertex indices"); - v_ext = (SimSel_VertExt *)MEM_mallocN(sizeof(SimSel_VertExt) * num_total, "vertex extra"); - - /* loop through all the vertices and fill the vertices/indices structure */ - BM_ITER_MESH (v, &v_iter, bm, BM_VERTS_OF_MESH) { - v_ext[i].v = v; - if (BMO_elem_flag_test(bm, v, VERT_MARK)) { - indices[idx] = i; - idx++; - } - - switch (type) { - case SIMVERT_FACE: - /* calling BM_vert_face_count every time is time consumming, so call it only once per vertex */ - v_ext[i].num_faces = BM_vert_face_count(v); - break; - - case SIMVERT_VGROUP: - if (CustomData_has_layer(&(bm->vdata), CD_MDEFORMVERT)) { - v_ext[i].dvert = CustomData_bmesh_get(&bm->vdata, v_ext[i].v->head.data, CD_MDEFORMVERT); - } - else { - v_ext[i].dvert = NULL; - } - break; - case SIMVERT_EDGE: - v_ext[i].num_edges = BM_vert_edge_count(v); - break; - } - - i++; - } - - /* select the vertices if any */ - for (i = 0; i < num_total; i++) { - v = v_ext[i].v; - if (!BMO_elem_flag_test(bm, v, VERT_MARK) && !BM_elem_flag_test(v, BM_ELEM_HIDDEN)) { - int cont = TRUE; - for (idx = 0; idx < num_sels && cont == TRUE; idx++) { - vs = v_ext[indices[idx]].v; - switch (type) { - case SIMVERT_NORMAL: - /* compare the angle between the normals */ - if (angle_normalized_v3v3(v->no, vs->no) <= thresh_radians) { - BMO_elem_flag_enable(bm, v, VERT_MARK); - cont = FALSE; - } - break; - case SIMVERT_FACE: - /* number of adjacent faces */ - if (v_ext[i].num_faces == v_ext[indices[idx]].num_faces) { - BMO_elem_flag_enable(bm, v, VERT_MARK); - cont = FALSE; - } - break; - - case SIMVERT_VGROUP: - if (v_ext[i].dvert != NULL && v_ext[indices[idx]].dvert != NULL) { - int v1, v2; - for (v1 = 0; v1 < v_ext[i].dvert->totweight && cont == 1; v1++) { - for (v2 = 0; v2 < v_ext[indices[idx]].dvert->totweight; v2++) { - if (v_ext[i].dvert->dw[v1].def_nr == v_ext[indices[idx]].dvert->dw[v2].def_nr) { - BMO_elem_flag_enable(bm, v, VERT_MARK); - cont = FALSE; - break; - } - } - } - } - break; - case SIMVERT_EDGE: - /* number of adjacent edges */ - if (v_ext[i].num_edges == v_ext[indices[idx]].num_edges) { - BMO_elem_flag_enable(bm, v, VERT_MARK); - cont = FALSE; - } - break; - } - } - } - } - - MEM_freeN(indices); - MEM_freeN(v_ext); - - BMO_slot_buffer_from_enabled_flag(bm, op, "vertout", BM_VERT, VERT_MARK); -} - /**************************************************************************** * * Cycle UVs for a face **************************************************************************** */ @@ -1245,6 +697,8 @@ typedef struct ElemNode { HeapNode *hn; /* heap node */ } ElemNode; +#define VERT_MARK 1 + void bmo_shortest_path_exec(BMesh *bm, BMOperator *op) { BMOIter vs_iter /* , vs2_iter */; /* selected verts iterator */ @@ -1256,7 +710,7 @@ void bmo_shortest_path_exec(BMesh *bm, BMOperator *op) ElemNode *vert_list = NULL; int num_total = 0 /*, num_sels = 0 */, i = 0; - int type = BMO_slot_int_get(op, "type"); + const int type = BMO_slot_int_get(op, "type"); BMO_ITER (vs, &vs_iter, bm, op, "startv", BM_VERT) { sv = vs; diff --git a/source/blender/collada/AnimationExporter.h b/source/blender/collada/AnimationExporter.h index 665c6999093..349930dea8f 100644 --- a/source/blender/collada/AnimationExporter.h +++ b/source/blender/collada/AnimationExporter.h @@ -35,10 +35,19 @@ extern "C" #include "DNA_armature_types.h" #include "DNA_material_types.h" +#include "BLI_math.h" +#include "BLI_string.h" +#include "BLI_listbase.h" +#include "BLI_utildefines.h" + #include "BKE_DerivedMesh.h" #include "BKE_fcurve.h" #include "BKE_animsys.h" #include "BKE_scene.h" +#include "BKE_action.h" // pose functions +#include "BKE_armature.h" +#include "BKE_object.h" + #ifdef NAN_BUILDINFO extern char build_rev[]; #endif @@ -46,14 +55,6 @@ extern char build_rev[]; #include "MEM_guardedalloc.h" -#include "BKE_action.h" // pose functions -#include "BKE_armature.h" -#include "BKE_object.h" - -#include "BLI_math.h" -#include "BLI_string.h" -#include "BLI_listbase.h" - #include "RNA_access.h" #include "COLLADASWSource.h" diff --git a/source/blender/collada/ArmatureImporter.h b/source/blender/collada/ArmatureImporter.h index eead45353af..a6b37287479 100644 --- a/source/blender/collada/ArmatureImporter.h +++ b/source/blender/collada/ArmatureImporter.h @@ -104,7 +104,7 @@ private: #endif void create_bone(SkinInfo& skin, COLLADAFW::Node *node, EditBone *parent, int totchild, - float parent_mat[][4], bArmature *arm); + float parent_mat[][4], bArmature *arm); void create_unskinned_bone(COLLADAFW::Node *node, EditBone *parent, int totchild, float parent_mat[][4], Object * ob_arm); diff --git a/source/blender/collada/DocumentExporter.cpp b/source/blender/collada/DocumentExporter.cpp index bd7ad16dabd..c491326519f 100644 --- a/source/blender/collada/DocumentExporter.cpp +++ b/source/blender/collada/DocumentExporter.cpp @@ -79,36 +79,38 @@ extern "C" #include "DNA_modifier_types.h" #include "DNA_userdef_types.h" -#include "BKE_DerivedMesh.h" -#include "BKE_fcurve.h" -#include "BKE_animsys.h" #include "BLI_path_util.h" #include "BLI_fileops.h" -#include "ED_keyframing.h" -#ifdef WITH_BUILDINFO -extern char build_rev[]; -#endif - -#include "MEM_guardedalloc.h" +#include "BLI_math.h" +#include "BLI_string.h" +#include "BLI_listbase.h" +#include "BLI_utildefines.h" +#include "BKE_DerivedMesh.h" +#include "BKE_action.h" // pose functions +#include "BKE_animsys.h" +#include "BKE_armature.h" #include "BKE_blender.h" // version info -#include "BKE_scene.h" +#include "BKE_fcurve.h" #include "BKE_global.h" +#include "BKE_image.h" #include "BKE_main.h" #include "BKE_material.h" -#include "BKE_action.h" // pose functions -#include "BKE_armature.h" -#include "BKE_image.h" #include "BKE_object.h" +#include "BKE_scene.h" -#include "BLI_math.h" -#include "BLI_string.h" -#include "BLI_listbase.h" +#include "ED_keyframing.h" +#ifdef WITH_BUILDINFO +extern char build_rev[]; +#endif + +#include "MEM_guardedalloc.h" #include "RNA_access.h" } #include "collada_internal.h" +#include "collada_utils.h" #include "DocumentExporter.h" extern bool bc_has_object_type(LinkNode *export_set, short obtype); diff --git a/source/blender/collada/GeometryExporter.cpp b/source/blender/collada/GeometryExporter.cpp index 24ce1ee117d..f33f0fa110d 100644 --- a/source/blender/collada/GeometryExporter.cpp +++ b/source/blender/collada/GeometryExporter.cpp @@ -38,6 +38,8 @@ #include "DNA_meshdata_types.h" extern "C" { + #include "BLI_utildefines.h" + #include "BKE_DerivedMesh.h" #include "BKE_main.h" #include "BKE_global.h" diff --git a/source/blender/collada/SceneExporter.cpp b/source/blender/collada/SceneExporter.cpp index 4aaff024cac..6d239ae0fb1 100644 --- a/source/blender/collada/SceneExporter.cpp +++ b/source/blender/collada/SceneExporter.cpp @@ -24,9 +24,13 @@ * \ingroup collada */ +extern "C" { + #include "BLI_utildefines.h" + #include "BKE_object.h" +} + #include "SceneExporter.h" #include "collada_utils.h" -#include "BKE_object.h" SceneExporter::SceneExporter(COLLADASW::StreamWriter *sw, ArmatureExporter *arm, const ExportSettings *export_settings) : COLLADASW::LibraryVisualScenes(sw), arm_exporter(arm), export_settings(export_settings) diff --git a/source/blender/collada/collada_internal.h b/source/blender/collada/collada_internal.h index c1f75f996ce..6eec6a1675e 100644 --- a/source/blender/collada/collada_internal.h +++ b/source/blender/collada/collada_internal.h @@ -88,6 +88,7 @@ extern std::string translate_id(const std::string &id); extern std::string id_name(void *id); +extern std::string get_geometry_id(Object *ob); extern std::string get_geometry_id(Object *ob, bool use_instantiation); extern std::string get_light_id(Object *ob); diff --git a/source/blender/collada/collada_utils.cpp b/source/blender/collada/collada_utils.cpp index 018d66c6f55..35844b549de 100644 --- a/source/blender/collada/collada_utils.cpp +++ b/source/blender/collada/collada_utils.cpp @@ -35,7 +35,6 @@ #include "collada_utils.h" extern "C" { - #include "DNA_modifier_types.h" #include "DNA_customdata_types.h" #include "DNA_object_types.h" @@ -44,6 +43,7 @@ extern "C" { #include "DNA_armature_types.h" #include "BLI_math.h" +#include "BLI_linklist.h" #include "BKE_context.h" #include "BKE_customdata.h" @@ -51,10 +51,7 @@ extern "C" { #include "BKE_object.h" #include "BKE_mesh.h" #include "BKE_scene.h" - #include "BKE_DerivedMesh.h" -#include "BLI_linklist.h" - #include "WM_api.h" // XXX hrm, see if we can do without this #include "WM_types.h" diff --git a/source/blender/collada/collada_utils.h b/source/blender/collada/collada_utils.h index b52115722fe..b8990c3fcdd 100644 --- a/source/blender/collada/collada_utils.h +++ b/source/blender/collada/collada_utils.h @@ -35,18 +35,19 @@ #include <vector> #include <map> +extern "C" { #include "DNA_object_types.h" #include "DNA_mesh_types.h" #include "DNA_customdata_types.h" #include "DNA_texture_types.h" -#include "BKE_context.h" -#include "BKE_object.h" - #include "DNA_scene_types.h" -extern "C" { -#include "BKE_DerivedMesh.h" #include "BLI_linklist.h" +#include "BLI_utildefines.h" + +#include "BKE_context.h" +#include "BKE_object.h" +#include "BKE_DerivedMesh.h" } #include "ExportSettings.h" diff --git a/source/blender/compositor/intern/COM_ExecutionSystem.cpp b/source/blender/compositor/intern/COM_ExecutionSystem.cpp index 57ff5c5c838..c6e0f6c2cfb 100644 --- a/source/blender/compositor/intern/COM_ExecutionSystem.cpp +++ b/source/blender/compositor/intern/COM_ExecutionSystem.cpp @@ -336,6 +336,16 @@ void ExecutionSystem::addSocketConnection(SocketConnection *connection) this->m_connections.push_back(connection); } +void ExecutionSystem::removeSocketConnection(SocketConnection *connection) +{ + for (vector<SocketConnection *>::iterator it = m_connections.begin(); it != m_connections.end(); ++it) { + if (*it == connection) { + this->m_connections.erase(it); + return; + } + } +} + void ExecutionSystem::findOutputExecutionGroup(vector<ExecutionGroup *> *result, CompositorPriority priority) const { diff --git a/source/blender/compositor/intern/COM_ExecutionSystem.h b/source/blender/compositor/intern/COM_ExecutionSystem.h index 56a60bf7a03..25f06108d96 100644 --- a/source/blender/compositor/intern/COM_ExecutionSystem.h +++ b/source/blender/compositor/intern/COM_ExecutionSystem.h @@ -189,6 +189,11 @@ public: void addSocketConnection(SocketConnection *connection); /** + * Remove a socket connection from the system. + */ + void removeSocketConnection(SocketConnection *connection); + + /** * @brief Convert all nodes to operations */ void convertToOperations(); diff --git a/source/blender/compositor/intern/COM_InputSocket.cpp b/source/blender/compositor/intern/COM_InputSocket.cpp index a9c280e0367..2493d4e5a27 100644 --- a/source/blender/compositor/intern/COM_InputSocket.cpp +++ b/source/blender/compositor/intern/COM_InputSocket.cpp @@ -122,6 +122,17 @@ void InputSocket::relinkConnections(InputSocket *relinkToSocket, int editorNode } } +void InputSocket::unlinkConnections(ExecutionSystem *system) +{ + SocketConnection *connection = getConnection(); + if (connection) { + system->removeSocketConnection(connection); + connection->getFromSocket()->removeConnection(connection); + setConnection(NULL); + delete connection; + } +} + bool InputSocket::isStatic() { if (isConnected()) { diff --git a/source/blender/compositor/intern/COM_InputSocket.h b/source/blender/compositor/intern/COM_InputSocket.h index 5970c9d5dd6..5cd4cf3beb7 100644 --- a/source/blender/compositor/intern/COM_InputSocket.h +++ b/source/blender/compositor/intern/COM_InputSocket.h @@ -108,7 +108,8 @@ public: void relinkConnections(InputSocket *relinkToSocket, int editorNodeInputSocketIndex, ExecutionSystem *system); /** - * @brief move all connections of this input socket to another socket + * @brief add a connection of this input socket to another socket + * @warning make sure to remove the original connection with \a unlinkConnections afterward. * @param relinkToSocket the socket to move to connections to * @param editorNodeInputSocketIndex index of the socket number of the bNode (used to retrieve the value for autoconnection) * @param system ExecutionSystem to update to @@ -116,6 +117,13 @@ public: void relinkConnectionsDuplicate(InputSocket *relinkToSocket, int editorNodeInputSocketIndex, ExecutionSystem *system); /** + * @brief remove all connections of this input socket. + * @warning \a relinkConnectionsDuplicate should be used to ensure this socket is still connected. + * @param system ExecutionSystem to update to + */ + void unlinkConnections(ExecutionSystem *system); + + /** * @brief set the resize mode * @param resizeMode the new resize mode. */ diff --git a/source/blender/compositor/intern/COM_MemoryBuffer.cpp b/source/blender/compositor/intern/COM_MemoryBuffer.cpp index bdbe21f82ea..357a4c1d4c0 100644 --- a/source/blender/compositor/intern/COM_MemoryBuffer.cpp +++ b/source/blender/compositor/intern/COM_MemoryBuffer.cpp @@ -160,7 +160,7 @@ void MemoryBuffer::writePixel(int x, int y, const float color[4]) if (x >= this->m_rect.xmin && x < this->m_rect.xmax && y >= this->m_rect.ymin && y < this->m_rect.ymax) { - const int offset = (this->m_chunkWidth * (y-this->m_rect.ymin) + x-this->m_rect.xmin) * COM_NUMBER_OF_CHANNELS; + const int offset = (this->m_chunkWidth * (y - this->m_rect.ymin) + x - this->m_rect.xmin) * COM_NUMBER_OF_CHANNELS; copy_v4_v4(&this->m_buffer[offset], color); } } @@ -170,7 +170,7 @@ void MemoryBuffer::addPixel(int x, int y, const float color[4]) if (x >= this->m_rect.xmin && x < this->m_rect.xmax && y >= this->m_rect.ymin && y < this->m_rect.ymax) { - const int offset = (this->m_chunkWidth * (y-this->m_rect.ymin) + x-this->m_rect.xmin) * COM_NUMBER_OF_CHANNELS; + const int offset = (this->m_chunkWidth * (y - this->m_rect.ymin) + x - this->m_rect.xmin) * COM_NUMBER_OF_CHANNELS; add_v4_v4(&this->m_buffer[offset], color); } } diff --git a/source/blender/compositor/intern/COM_NodeOperation.h b/source/blender/compositor/intern/COM_NodeOperation.h index 9964c27bd46..42d90eca38f 100644 --- a/source/blender/compositor/intern/COM_NodeOperation.h +++ b/source/blender/compositor/intern/COM_NodeOperation.h @@ -163,7 +163,10 @@ public: * @param clMemToCleanUp all created cl_mem references must be added to this list. Framework will clean this after execution * @param clKernelsToCleanUp all created cl_kernel references must be added to this list. Framework will clean this after execution */ - virtual void executeOpenCL(OpenCLDevice *device, MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer, MemoryBuffer **inputMemoryBuffers, list<cl_mem> *clMemToCleanUp, list<cl_kernel> *clKernelsToCleanUp) {} + virtual void executeOpenCL(OpenCLDevice *device, + MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer, + MemoryBuffer **inputMemoryBuffers, list<cl_mem> *clMemToCleanUp, + list<cl_kernel> *clKernelsToCleanUp) {} virtual void deinitExecution(); bool isResolutionSet() { diff --git a/source/blender/compositor/intern/COM_OutputSocket.cpp b/source/blender/compositor/intern/COM_OutputSocket.cpp index f23a48979da..50e9b75b072 100644 --- a/source/blender/compositor/intern/COM_OutputSocket.cpp +++ b/source/blender/compositor/intern/COM_OutputSocket.cpp @@ -54,6 +54,16 @@ void OutputSocket::addConnection(SocketConnection *connection) this->m_connections.push_back(connection); } +void OutputSocket::removeConnection(SocketConnection *connection) +{ + for (vector<SocketConnection *>::iterator it = m_connections.begin(); it != m_connections.end(); ++it) { + if (*it == connection) { + m_connections.erase(it); + return; + } + } +} + void OutputSocket::relinkConnections(OutputSocket *relinkToSocket, bool single) { if (isConnected()) { diff --git a/source/blender/compositor/intern/COM_OutputSocket.h b/source/blender/compositor/intern/COM_OutputSocket.h index 63f24451b84..709005a6de0 100644 --- a/source/blender/compositor/intern/COM_OutputSocket.h +++ b/source/blender/compositor/intern/COM_OutputSocket.h @@ -50,6 +50,7 @@ public: OutputSocket(DataType datatype, int inputSocketDataTypeDeterminatorIndex); OutputSocket(OutputSocket *from); void addConnection(SocketConnection *connection); + void removeConnection(SocketConnection *connection); SocketConnection *getConnection(unsigned int index) { return this->m_connections[index]; } const int isConnected() const; int isOutputSocket() const; diff --git a/source/blender/compositor/intern/COM_WorkScheduler.cpp b/source/blender/compositor/intern/COM_WorkScheduler.cpp index e9767c41230..724abb59bcf 100644 --- a/source/blender/compositor/intern/COM_WorkScheduler.cpp +++ b/source/blender/compositor/intern/COM_WorkScheduler.cpp @@ -106,13 +106,11 @@ void **g_highlightedNodesRead; void COM_startReadHighlights() { - if (!g_highlightInitialized) - { + if (!g_highlightInitialized) { return; } - if (g_highlightedNodesRead) - { + if (g_highlightedNodesRead) { MEM_freeN(g_highlightedNodesRead); } diff --git a/source/blender/compositor/nodes/COM_HueSaturationValueNode.cpp b/source/blender/compositor/nodes/COM_HueSaturationValueNode.cpp index 9b55b809212..29e10db0758 100644 --- a/source/blender/compositor/nodes/COM_HueSaturationValueNode.cpp +++ b/source/blender/compositor/nodes/COM_HueSaturationValueNode.cpp @@ -50,7 +50,7 @@ void HueSaturationValueNode::convertToOperations(ExecutionSystem *graph, Composi ChangeHSVOperation *changeHSV = new ChangeHSVOperation(); MixBlendOperation *blend = new MixBlendOperation(); - colorSocket->relinkConnections(rgbToHSV->getInputSocket(0), 0, graph); + colorSocket->relinkConnections(rgbToHSV->getInputSocket(0), 1, graph); addLink(graph, rgbToHSV->getOutputSocket(), changeHSV->getInputSocket(0)); addLink(graph, changeHSV->getOutputSocket(), hsvToRGB->getInputSocket(0)); addLink(graph, hsvToRGB->getOutputSocket(), blend->getInputSocket(2)); diff --git a/source/blender/compositor/nodes/COM_SeparateRGBANode.cpp b/source/blender/compositor/nodes/COM_SeparateRGBANode.cpp index 67ac6ffc388..7fcdebadb46 100644 --- a/source/blender/compositor/nodes/COM_SeparateRGBANode.cpp +++ b/source/blender/compositor/nodes/COM_SeparateRGBANode.cpp @@ -70,4 +70,7 @@ void SeparateRGBANode::convertToOperations(ExecutionSystem *graph, CompositorCon outputASocket->relinkConnections(operation->getOutputSocket(0)); graph->addOperation(operation); } + + /* remove the original connection to the node, this has been duplicated for all operations */ + imageSocket->unlinkConnections(graph); } diff --git a/source/blender/compositor/nodes/COM_ViewerNode.cpp b/source/blender/compositor/nodes/COM_ViewerNode.cpp index d67e9e274b0..f44470a9b9a 100644 --- a/source/blender/compositor/nodes/COM_ViewerNode.cpp +++ b/source/blender/compositor/nodes/COM_ViewerNode.cpp @@ -52,8 +52,7 @@ void ViewerNode::convertToOperations(ExecutionSystem *graph, CompositorContext * viewerOperation->setDisplaySettings(context->getDisplaySettings()); viewerOperation->setResolutionInputSocketIndex(0); - if (!imageSocket->isConnected()) - { + if (!imageSocket->isConnected()) { if (alphaSocket->isConnected()) { viewerOperation->setResolutionInputSocketIndex(1); } diff --git a/source/blender/compositor/operations/COM_BokehBlurOperation.h b/source/blender/compositor/operations/COM_BokehBlurOperation.h index 37483d3dc69..74ca6b7b058 100644 --- a/source/blender/compositor/operations/COM_BokehBlurOperation.h +++ b/source/blender/compositor/operations/COM_BokehBlurOperation.h @@ -59,6 +59,9 @@ public: void setSize(float size) { this->m_size = size; this->m_sizeavailable = true; } - void executeOpenCL(OpenCLDevice *device, MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer, MemoryBuffer **inputMemoryBuffers, list<cl_mem> *clMemToCleanUp, list<cl_kernel> *clKernelsToCleanUp); + void executeOpenCL(OpenCLDevice *device, + MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer, + MemoryBuffer **inputMemoryBuffers, list<cl_mem> *clMemToCleanUp, + list<cl_kernel> *clKernelsToCleanUp); }; #endif diff --git a/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.cpp index 8c5e5faf12a..1ad888e5989 100644 --- a/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.cpp @@ -123,7 +123,7 @@ void GaussianAlphaXBlurOperation::executePixel(float output[4], int x, int y, vo float value_max = finv_test(buffer[(x * 4) + (y * 4 * bufferwidth)], do_invert); /* init with the current color to avoid unneeded lookups */ float distfacinv_max = 1.0f; /* 0 to 1 */ - for (int nx = minx; nx < maxx; nx += step) { + for (int nx = minx; nx <= maxx; nx += step) { const int index = (nx - x) + this->m_rad; float value = finv_test(buffer[bufferindex], do_invert); float multiplier; diff --git a/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.cpp index 197715595ed..60a325c5f38 100644 --- a/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.cpp @@ -121,7 +121,7 @@ void GaussianAlphaYBlurOperation::executePixel(float output[4], int x, int y, vo float value_max = finv_test(buffer[(x * 4) + (y * 4 * bufferwidth)], do_invert); /* init with the current color to avoid unneeded lookups */ float distfacinv_max = 1.0f; /* 0 to 1 */ - for (int ny = miny; ny < maxy; ny += step) { + for (int ny = miny; ny <= maxy; ny += step) { int bufferindex = ((minx - bufferstartx) * 4) + ((ny - bufferstarty) * 4 * bufferwidth); const int index = (ny - y) + this->m_rad; diff --git a/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp index 44bce6308e8..2d662c1061e 100644 --- a/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp @@ -236,7 +236,7 @@ void GaussianBlurReferenceOperation::initExecution() /* horizontal */ m_radx = (float)this->m_data->sizex; - int imgx = getWidth()/2; + int imgx = getWidth() / 2; if (m_radx > imgx) m_radx = imgx; else if (m_radx < 1) @@ -245,7 +245,7 @@ void GaussianBlurReferenceOperation::initExecution() /* vertical */ m_rady = (float)this->m_data->sizey; - int imgy = getHeight()/2; + int imgy = getHeight() / 2; if (m_rady > imgy) m_rady = imgy; else if (m_rady < 1) @@ -344,8 +344,8 @@ bool GaussianBlurReferenceOperation::determineDependingAreaOfInterest(rcti *inpu return true; } else { - int addx = this->m_data->sizex+2; - int addy = this->m_data->sizey+2; + int addx = this->m_data->sizex + 2; + int addy = this->m_data->sizey + 2; newInput.xmax = input->xmax + addx; newInput.xmin = input->xmin - addx; newInput.ymax = input->ymax + addy; diff --git a/source/blender/compositor/operations/COM_GaussianXBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianXBlurOperation.cpp index 3ab60a1faa9..f6c30f7097c 100644 --- a/source/blender/compositor/operations/COM_GaussianXBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_GaussianXBlurOperation.cpp @@ -96,7 +96,7 @@ void GaussianXBlurOperation::executePixel(float output[4], int x, int y, void *d int step = getStep(); int offsetadd = getOffsetAdd(); int bufferindex = ((minx - bufferstartx) * 4) + ((miny - bufferstarty) * 4 * bufferwidth); - for (int nx = minx, index = (minx - x) + this->m_rad; nx < maxx; nx += step, index += step) { + for (int nx = minx, index = (minx - x) + this->m_rad; nx <= maxx; nx += step, index += step) { const float multiplier = this->m_gausstab[index]; madd_v4_v4fl(color_accum, &buffer[bufferindex], multiplier); multiplier_accum += multiplier; diff --git a/source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp index 02627bae5ed..433771d2c0c 100644 --- a/source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp @@ -96,7 +96,7 @@ void GaussianYBlurOperation::executePixel(float output[4], int x, int y, void *d int index; int step = getStep(); const int bufferIndexx = ((minx - bufferstartx) * 4); - for (int ny = miny; ny < maxy; ny += step) { + for (int ny = miny; ny <= maxy; ny += step) { index = (ny - y) + this->m_rad; int bufferindex = bufferIndexx + ((ny - bufferstarty) * 4 * bufferwidth); const float multiplier = this->m_gausstab[index]; diff --git a/source/blender/compositor/operations/COM_MovieDistortionOperation.cpp b/source/blender/compositor/operations/COM_MovieDistortionOperation.cpp index 0af5ec2d06c..df48c7a6716 100644 --- a/source/blender/compositor/operations/COM_MovieDistortionOperation.cpp +++ b/source/blender/compositor/operations/COM_MovieDistortionOperation.cpp @@ -33,8 +33,7 @@ vector<DistortionCache *> s_cache; void deintializeDistortionCache(void) { - while (s_cache.size()>0) - { + while (s_cache.size() > 0) { DistortionCache * cache = s_cache.back(); s_cache.pop_back(); delete cache; @@ -61,8 +60,7 @@ void MovieDistortionOperation::initExecution() BKE_movieclip_user_set_frame(&clipUser, this->m_framenumber); BKE_movieclip_get_size(this->m_movieClip, &clipUser, &calibration_width, &calibration_height); - for (unsigned int i = 0; i < s_cache.size(); i++) - { + for (unsigned int i = 0; i < s_cache.size(); i++) { DistortionCache *c = (DistortionCache *)s_cache[i]; if (c->isCacheFor(this->m_movieClip, this->m_width, this->m_height, calibration_width, calibration_height, this->m_distortion)) @@ -86,15 +84,12 @@ void MovieDistortionOperation::deinitExecution() { this->m_inputOperation = NULL; this->m_movieClip = NULL; - while (s_cache.size() > COM_DISTORTIONCACHE_MAXSIZE) - { + while (s_cache.size() > COM_DISTORTIONCACHE_MAXSIZE) { double minTime = PIL_check_seconds_timer(); vector<DistortionCache*>::iterator minTimeIterator = s_cache.begin(); - for (vector<DistortionCache*>::iterator it = s_cache.begin(); it < s_cache.end(); it ++) - { + for (vector<DistortionCache*>::iterator it = s_cache.begin(); it < s_cache.end(); it ++) { DistortionCache * cache = *it; - if (cache->getTimeLastUsage()<minTime) - { + if (cache->getTimeLastUsage() < minTime) { minTime = cache->getTimeLastUsage(); minTimeIterator = it; } diff --git a/source/blender/compositor/operations/COM_OutputFileOperation.cpp b/source/blender/compositor/operations/COM_OutputFileOperation.cpp index 1bc262a4d27..7d05202df96 100644 --- a/source/blender/compositor/operations/COM_OutputFileOperation.cpp +++ b/source/blender/compositor/operations/COM_OutputFileOperation.cpp @@ -94,8 +94,8 @@ static void write_buffer_rect(rcti *rect, const bNodeTree *tree, OutputSingleLayerOperation::OutputSingleLayerOperation( - const RenderData *rd, const bNodeTree *tree, DataType datatype, ImageFormatData *format, const char *path, - const ColorManagedViewSettings *viewSettings, const ColorManagedDisplaySettings *displaySettings) + const RenderData *rd, const bNodeTree *tree, DataType datatype, ImageFormatData *format, const char *path, + const ColorManagedViewSettings *viewSettings, const ColorManagedDisplaySettings *displaySettings) { this->m_rd = rd; this->m_tree = tree; diff --git a/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.cpp b/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.cpp index 00e35f2c9d8..5cc02a1ed65 100644 --- a/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.cpp +++ b/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.cpp @@ -81,7 +81,7 @@ bool ProjectorLensDistortionOperation::determineDependingAreaOfInterest(rcti *in } else { rcti dispInput; - BLI_rcti_init(&dispInput, 0,5,0,5); + BLI_rcti_init(&dispInput, 0, 5, 0, 5); if (this->getInputOperation(1)->determineDependingAreaOfInterest(&dispInput, readOperation, output)) { return true; } diff --git a/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp b/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp index 52a9e2a4d8c..61720c7676d 100644 --- a/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp @@ -118,7 +118,7 @@ void VariableSizeBokehBlurOperation::executePixel(float output[4], int x, int y, #ifdef COM_DEFOCUS_SEARCH float search[4]; - this->m_inputSearchProgram->read(search, x/InverseSearchRadiusOperation::DIVIDER, y / InverseSearchRadiusOperation::DIVIDER, NULL); + this->m_inputSearchProgram->read(search, x / InverseSearchRadiusOperation::DIVIDER, y / InverseSearchRadiusOperation::DIVIDER, NULL); int minx = search[0]; int miny = search[1]; int maxx = search[2]; @@ -298,9 +298,9 @@ voi *InverseSearchRadiusOperation::initializeTileData(rcti *rect) int rx = x * DIVIDER; int ry = y * DIVIDER; buffer[offset] = MAX2(rx - m_maxBlur, 0); - buffer[offset+1] = MAX2(ry- m_maxBlur, 0); - buffer[offset+2] = MIN2(rx+DIVIDER + m_maxBlur, width); - buffer[offset+3] = MIN2(ry+DIVIDER + m_maxBlur, height); + buffer[offset + 1] = MAX2(ry - m_maxBlur, 0); + buffer[offset + 2] = MIN2(rx + DIVIDER + m_maxBlur, width); + buffer[offset + 3] = MIN2(ry + DIVIDER + m_maxBlur, height); offset += 4; } } diff --git a/source/blender/compositor/operations/COM_ViewerBaseOperation.cpp b/source/blender/compositor/operations/COM_ViewerBaseOperation.cpp index 55a001530ee..4d4c1199f3e 100644 --- a/source/blender/compositor/operations/COM_ViewerBaseOperation.cpp +++ b/source/blender/compositor/operations/COM_ViewerBaseOperation.cpp @@ -79,8 +79,7 @@ void ViewerBaseOperation::initImage() BLI_unlock_thread(LOCK_DRAW_IMAGE); } - if (m_doDepthBuffer) - { + if (m_doDepthBuffer) { addzbuffloatImBuf(ibuf); } BLI_unlock_thread(LOCK_DRAW_IMAGE); @@ -96,8 +95,7 @@ void ViewerBaseOperation::initImage() */ this->m_ibuf = ibuf; - if (m_doDepthBuffer) - { + if (m_doDepthBuffer) { this->m_depthBuffer = ibuf->zbuf_float; } diff --git a/source/blender/compositor/operations/COM_WriteBufferOperation.cpp b/source/blender/compositor/operations/COM_WriteBufferOperation.cpp index 273c10b60ac..17c8f4d9fd1 100644 --- a/source/blender/compositor/operations/COM_WriteBufferOperation.cpp +++ b/source/blender/compositor/operations/COM_WriteBufferOperation.cpp @@ -110,7 +110,8 @@ void WriteBufferOperation::executeRegion(rcti *rect, unsigned int tileNumber) memoryBuffer->setCreatedState(); } -void WriteBufferOperation::executeOpenCLRegion(OpenCLDevice *device, rcti *rect, unsigned int chunkNumber, MemoryBuffer **inputMemoryBuffers, MemoryBuffer *outputBuffer) +void WriteBufferOperation::executeOpenCLRegion(OpenCLDevice *device, rcti *rect, unsigned int chunkNumber, + MemoryBuffer **inputMemoryBuffers, MemoryBuffer *outputBuffer) { float *outputFloatBuffer = outputBuffer->getBuffer(); cl_int error; diff --git a/source/blender/datatoc/datatoc.c b/source/blender/datatoc/datatoc.c index a7da037ff16..379658bb4c4 100644 --- a/source/blender/datatoc/datatoc.c +++ b/source/blender/datatoc/datatoc.c @@ -49,7 +49,6 @@ static char *basename(char *string) int main(int argc, char **argv) { FILE *fpin, *fpout; - char sizest[256]; long size; int i; @@ -79,8 +78,6 @@ int main(int argc, char **argv) for (i = 0; i < (int)strlen(argv[1]); i++) if (argv[1][i] == '.') argv[1][i] = '_'; - sprintf(sizest, "%d", (int)size); - fpout = fopen(argv[2], "w"); if (!fpout) { fprintf(stderr, "Unable to open output <%s>\n", argv[2]); @@ -88,7 +85,7 @@ int main(int argc, char **argv) } fprintf(fpout, "/* DataToC output of file <%s> */\n\n", argv[1]); - fprintf(fpout, "int datatoc_%s_size = %s;\n", argv[1], sizest); + fprintf(fpout, "int datatoc_%s_size = %d;\n", argv[1], (int)size); fprintf(fpout, "char datatoc_%s[] = {\n", argv[1]); while (size--) { /* if we want to open in an editor diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c index 81ebca7b2fb..c353b64607d 100644 --- a/source/blender/editors/animation/anim_channels_defines.c +++ b/source/blender/editors/animation/anim_channels_defines.c @@ -753,7 +753,7 @@ static void acf_group_color(bAnimContext *ac, bAnimListElem *ale, float r_color[ /* highlight only for active */ if (ale->flag & AGRP_ACTIVE) - copy_v3_v3_char((char *)cp, agrp->cs.active); + copy_v3_v3_char((char *)cp, agrp->cs.select); else copy_v3_v3_char((char *)cp, agrp->cs.solid); diff --git a/source/blender/editors/animation/fmodifier_ui.c b/source/blender/editors/animation/fmodifier_ui.c index a591b51b0b3..79a4c9a769d 100644 --- a/source/blender/editors/animation/fmodifier_ui.c +++ b/source/blender/editors/animation/fmodifier_ui.c @@ -167,7 +167,7 @@ static void draw_modifier__generator(uiLayout *layout, ID *id, FModifier *fcm, s uiDefBut(block, LABEL, 1, "y =", 0, 0, 40, 20, NULL, 0.0, 0.0, 0, 0, ""); /* coefficient */ - uiDefButF(block, NUM, B_FMODIFIER_REDRAW, "", 0, 0, bwidth/2, 20, cp, -UI_FLT_MAX, UI_FLT_MAX, + uiDefButF(block, NUM, B_FMODIFIER_REDRAW, "", 0, 0, bwidth / 2, 20, cp, -UI_FLT_MAX, UI_FLT_MAX, 10, 3, TIP_("Coefficient for polynomial")); /* 'x' param (and '+' if necessary) */ diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c index 4f16c1a6622..8ba330e7c3c 100644 --- a/source/blender/editors/animation/keyframing.c +++ b/source/blender/editors/animation/keyframing.c @@ -479,10 +479,10 @@ static short new_key_needed(FCurve *fcu, float cFrame, float nValue) /* Frame in which to add a new-keyframe occurs after all other keys * -> If there are at least two existing keyframes, then if the values of the - * last two keyframes and the new-keyframe match, the last existing keyframe - * gets deleted as it is no longer required. + * last two keyframes and the new-keyframe match, the last existing keyframe + * gets deleted as it is no longer required. * -> Otherwise, a keyframe is just added. 1.0 is added so that fake-2nd-to-last - * keyframe is not equal to last keyframe. + * keyframe is not equal to last keyframe. */ bezt = (fcu->bezt + (fcu->totvert - 1)); valA = bezt->vec[1][1]; diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c index e7586311312..9152ea8e198 100644 --- a/source/blender/editors/armature/meshlaplacian.c +++ b/source/blender/editors/armature/meshlaplacian.c @@ -1226,7 +1226,7 @@ static void harmonic_ray_callback(void *userdata, int index, const BVHTreeRay *r hit->dist = dist; copy_v3_v3(hit->co, co); - isec->isect = dot_v3v3(no, ray->direction) <= 0.0; + isec->isect = (dot_v3v3(no, ray->direction) <= 0.0f); isec->labda = dist; isec->face = mf; } diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index 9ae5d3ca557..485d73974cd 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -5641,8 +5641,8 @@ static int select_nth_exec(bContext *C, wmOperator *op) void CURVE_OT_select_nth(wmOperatorType *ot) { /* identifiers */ - ot->name = "Select Nth"; - ot->description = ""; + ot->name = "Checker Deselect"; + ot->description = "Deselect every other vertex"; ot->idname = "CURVE_OT_select_nth"; /* api callbacks */ diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c index 2d039cfaf7f..d92c20a1265 100644 --- a/source/blender/editors/curve/editfont.c +++ b/source/blender/editors/curve/editfont.c @@ -94,7 +94,8 @@ static char findaccent(char char1, unsigned int code) } else if (char1 == 'c') { if (code == ',') new = 231; - if (code == '|') new = 162; + else if (code == '|') new = 162; + else if (code == 'o') new = 169; } else if (char1 == 'e') { if (code == '`') new = 232; @@ -120,10 +121,18 @@ static char findaccent(char char1, unsigned int code) else if (code == '/') new = 248; else if (code == '-') new = 186; else if (code == 'e') new = 143; + else if (code == 'c') new = 169; + else if (code == 'r') new = 174; + } + else if (char1 == 'r') { + if (code == 'o') new = 174; } else if (char1 == 's') { if (code == 's') new = 167; } + else if (char1 == 't') { + if (code == 'm') new = 153; + } else if (char1 == 'u') { if (code == '`') new = 249; else if (code == 39) new = 250; @@ -1251,8 +1260,12 @@ static int insert_text_invoke(bContext *C, wmOperator *op, wmEvent *evt) else ascii = 9; } - else if (event == BACKSPACEKEY) - ascii = 0; + + if (event == BACKSPACEKEY) { + if (alt && cu->len != 0 && cu->pos > 0) + accentcode = 1; + return OPERATOR_PASS_THROUGH; + } if (val && (ascii || evt->utf8_buf[0])) { /* handle case like TAB (== 9) */ @@ -1263,19 +1276,19 @@ static int insert_text_invoke(bContext *C, wmOperator *op, wmEvent *evt) (evt->utf8_buf[0])) { - if (evt->utf8_buf[0]) { - BLI_strncpy_wchar_from_utf8(inserted_text, evt->utf8_buf, 1); - ascii = inserted_text[0]; - insert_into_textbuf(obedit, ascii); - accentcode = 0; - } - else if (accentcode) { + if (accentcode) { if (cu->pos > 0) { inserted_text[0] = findaccent(ef->textbuf[cu->pos - 1], ascii); ef->textbuf[cu->pos - 1] = inserted_text[0]; } accentcode = 0; } + else if (evt->utf8_buf[0]) { + BLI_strncpy_wchar_from_utf8(inserted_text, evt->utf8_buf, 1); + ascii = inserted_text[0]; + insert_into_textbuf(obedit, ascii); + accentcode = 0; + } else if (cu->len < MAXTEXT - 1) { if (alt) { /* might become obsolete, apple has default values for this, other OS's too? */ @@ -1312,12 +1325,6 @@ static int insert_text_invoke(bContext *C, wmOperator *op, wmEvent *evt) text_update_edited(C, scene, obedit, 1, FO_EDIT); } } - else if (val && event == BACKSPACEKEY) { - if (alt && cu->len != 0 && cu->pos > 0) - accentcode = 1; - - return OPERATOR_PASS_THROUGH; - } else return OPERATOR_PASS_THROUGH; @@ -1330,7 +1337,8 @@ static int insert_text_invoke(bContext *C, wmOperator *op, wmEvent *evt) } /* reset property? */ - accentcode = 0; + if (val == 0) + accentcode = 0; return OPERATOR_FINISHED; } diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index 42ea924522c..9bfd89075af 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -1648,7 +1648,7 @@ static int gpencil_draw_invoke(bContext *C, wmOperator *op, wmEvent *event) * painting should start immediately. Otherwise, this was called from a toolbar, in which * case we should wait for the mouse to be clicked. */ - if (event->type) { + if (event->val == KM_PRESS) { /* hotkey invoked - start drawing */ //printf("\tGP - set first spot\n"); p->status = GP_STATUS_PAINTING; @@ -1723,7 +1723,7 @@ static void gpencil_stroke_end(wmOperator *op) static int gpencil_draw_modal(bContext *C, wmOperator *op, wmEvent *event) { tGPsdata *p = op->customdata; - int estate = OPERATOR_PASS_THROUGH; /* default exit state - not handled, so let others have a share of the pie */ + int estate = OPERATOR_RUNNING_MODAL; /* default exit state - we don't pass on events, GP is used with key-modifiers */ /* if (event->type == NDOF_MOTION) * return OPERATOR_PASS_THROUGH; diff --git a/source/blender/editors/include/ED_mask.h b/source/blender/editors/include/ED_mask.h index dc40b687dfd..46ed9798d32 100644 --- a/source/blender/editors/include/ED_mask.h +++ b/source/blender/editors/include/ED_mask.h @@ -88,8 +88,8 @@ void free_gpcopybuf(void); void copy_gpdata(void); void paste_gpdata(void); - void snap_masklayer_frames(struct MaskLayer *masklay, short mode); - void mirror_masklayer_frames(struct MaskLayer *masklay, short mode); +void snap_masklayer_frames(struct MaskLayer *masklay, short mode); +void mirror_masklayer_frames(struct MaskLayer *masklay, short mode); #endif #endif /* __ED_MASK_H__ */ diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index 078762065b4..5ffcfbd94f0 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -250,7 +250,7 @@ void ED_mesh_update(struct Mesh *mesh, struct bContext *C, int calc_edges, int c int ED_mesh_uv_texture_add(struct bContext *C, struct Mesh *me, const char *name, int active_set); int ED_mesh_uv_texture_remove(struct bContext *C, struct Object *ob, struct Mesh *me); int ED_mesh_uv_loop_reset(struct bContext *C, struct Mesh *me); -int ED_mesh_uv_loop_reset_ex(struct bContext *C, struct Mesh *me, const int layernum); +int ED_mesh_uv_loop_reset_ex(struct Mesh *me, const int layernum); int ED_mesh_color_add(struct bContext *C, struct Scene *scene, struct Object *ob, struct Mesh *me, const char *name, int active_set); int ED_mesh_color_remove(struct bContext *C, struct Object *ob, struct Mesh *me); int ED_mesh_color_remove_named(struct bContext *C, struct Object *ob, struct Mesh *me, const char *name); diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c index a73954e2075..469bd11215e 100644 --- a/source/blender/editors/interface/interface_draw.c +++ b/source/blender/editors/interface/interface_draw.c @@ -643,7 +643,7 @@ static void draw_scope_end(const rctf *rect, GLint *scissor) /* scale widget */ scaler_x1 = rect->xmin + BLI_rctf_size_x(rect) / 2 - SCOPE_RESIZE_PAD; - scaler_x2 = rect->xmin + BLI_rctf_size_y(rect) / 2 + SCOPE_RESIZE_PAD; + scaler_x2 = rect->xmin + BLI_rctf_size_x(rect) / 2 + SCOPE_RESIZE_PAD; glColor4f(0.f, 0.f, 0.f, 0.25f); fdrawline(scaler_x1, rect->ymin - 4, scaler_x2, rect->ymin - 4); diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 55b20bddd80..6d262daab12 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -4933,8 +4933,7 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, wmEvent *event) if (but->flag & UI_BUT_DISABLED) return WM_UI_HANDLER_CONTINUE; - if ((data->state == BUTTON_STATE_HIGHLIGHT) || (event->type == EVT_DROP)) - { + if ((data->state == BUTTON_STATE_HIGHLIGHT) || (event->type == EVT_DROP)) { /* handle copy-paste */ if (ELEM(event->type, CKEY, VKEY) && event->val == KM_PRESS && (event->ctrl || event->oskey)) { @@ -6308,67 +6307,75 @@ static char ui_menu_scroll_test(uiBlock *block, int my) { if (block->flag & (UI_BLOCK_CLIPTOP | UI_BLOCK_CLIPBOTTOM)) { if (block->flag & UI_BLOCK_CLIPTOP) - if (my > block->rect.ymax - 14) + if (my > block->rect.ymax - UI_MENU_SCROLL_MOUSE) return 't'; if (block->flag & UI_BLOCK_CLIPBOTTOM) - if (my < block->rect.ymin + 14) + if (my < block->rect.ymin + UI_MENU_SCROLL_MOUSE) return 'b'; } return 0; } -static int ui_menu_scroll(ARegion *ar, uiBlock *block, int my) +static int ui_menu_scroll(ARegion *ar, uiBlock *block, int my, uiBut *to_bt) { - char test = ui_menu_scroll_test(block, my); - - if (test) { - uiBut *b1 = block->buttons.first; - uiBut *b2 = block->buttons.last; - uiBut *bnext; - uiBut *bprev; - int dy = 0; - - /* get first and last visible buttons */ - while (b1 && ui_but_next(b1) && (b1->flag & UI_SCROLLED)) - b1 = ui_but_next(b1); - while (b2 && ui_but_prev(b2) && (b2->flag & UI_SCROLLED)) - b2 = ui_but_prev(b2); - /* skips separators */ - bnext = ui_but_next(b1); - bprev = ui_but_prev(b2); + uiBut *bt; + float dy = 0.0f; + + if (to_bt) { + /* scroll to activated button */ + if (block->flag & UI_BLOCK_CLIPTOP) { + if (to_bt->rect.ymax > block->rect.ymax - UI_MENU_SCROLL_ARROW) + dy = block->rect.ymax - to_bt->rect.ymax - UI_MENU_SCROLL_ARROW; + } + if (block->flag & UI_BLOCK_CLIPBOTTOM) { + if (to_bt->rect.ymin < block->rect.ymin + UI_MENU_SCROLL_ARROW) + dy = block->rect.ymin - to_bt->rect.ymin + UI_MENU_SCROLL_ARROW; + } + } + else { + /* scroll when mouse over arrow buttons */ + char test = ui_menu_scroll_test(block, my); + + if (test == 't') + dy = -UI_UNIT_Y; /* scroll to the top */ + else if (test == 'b') + dy = UI_UNIT_Y; /* scroll to the bottom */ + } + + if (dy != 0.0f) { + if (dy < 0.0f) { + /* stop at top item, extra 0.5 unit Y makes it snap nicer */ + float ymax = -FLT_MAX; + + for (bt = block->buttons.first; bt; bt = bt->next) + ymax = max_ff(ymax, bt->rect.ymax); + + if (ymax + dy - UI_UNIT_Y*0.5f < block->rect.ymax - UI_MENU_SCROLL_PAD) + dy = block->rect.ymax - ymax - UI_MENU_SCROLL_PAD; + } + else { + /* stop at bottom item, extra 0.5 unit Y makes it snap nicer */ + float ymin = FLT_MAX; + + for (bt = block->buttons.first; bt; bt = bt->next) + ymin = min_ff(ymin, bt->rect.ymin); + + if (ymin + dy + UI_UNIT_Y*0.5f > block->rect.ymin + UI_MENU_SCROLL_PAD) + dy = block->rect.ymin - ymin + UI_MENU_SCROLL_PAD; + } + + /* apply scroll offset */ + for (bt = block->buttons.first; bt; bt = bt->next) { + bt->rect.ymin += dy; + bt->rect.ymax += dy; + } + + /* set flags again */ + ui_popup_block_scrolltest(block); - if (bnext == NULL || bprev == NULL) - return 0; + ED_region_tag_redraw(ar); - if (test == 't') { - /* bottom button is first button */ - if (b1->rect.ymin < b2->rect.ymin) - dy = bnext->rect.ymin - b1->rect.ymin; - /* bottom button is last button */ - else - dy = bprev->rect.ymin - b2->rect.ymin; - } - else if (test == 'b') { - /* bottom button is first button */ - if (b1->rect.ymin < b2->rect.ymin) - dy = b1->rect.ymin - bnext->rect.ymin; - /* bottom button is last button */ - else - dy = b2->rect.ymin - bprev->rect.ymin; - } - if (dy) { - - for (b1 = block->buttons.first; b1; b1 = b1->next) { - b1->rect.ymin -= dy; - b1->rect.ymax -= dy; - } - /* set flags again */ - ui_popup_block_scrolltest(block); - - ED_region_tag_redraw(ar); - - return 1; - } + return 1; } return 0; @@ -6404,7 +6411,7 @@ static int ui_handle_menu_event(bContext *C, wmEvent *event, uiPopupBlockHandle } else if (event->type == TIMER) { if (event->customdata == menu->scrolltimer) - ui_menu_scroll(ar, block, my); + ui_menu_scroll(ar, block, my, NULL); } else { /* for ui_mouse_motion_towards_block */ @@ -6499,8 +6506,10 @@ static int ui_handle_menu_event(bContext *C, wmEvent *event, uiPopupBlockHandle but = ui_but_next(but); } - if (but) + if (but) { ui_handle_button_activate(C, ar, but, BUTTON_ACTIVATE); + ui_menu_scroll(ar, block, my, but); + } } if (!but) { @@ -6526,6 +6535,7 @@ static int ui_handle_menu_event(bContext *C, wmEvent *event, uiPopupBlockHandle if (bt) { ui_handle_button_activate(C, ar, bt, BUTTON_ACTIVATE); + ui_menu_scroll(ar, block, my, bt); } } } diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index 98b75060aa8..16159e0f73a 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -97,6 +97,11 @@ typedef enum { UI_WTYPE_PROGRESSBAR } uiWidgetTypeEnum; +/* menu scrolling */ +#define UI_MENU_SCROLL_ARROW 12 +#define UI_MENU_SCROLL_MOUSE (UI_MENU_SCROLL_ARROW + 2) +#define UI_MENU_SCROLL_PAD 4 + /* panel limits */ #define UI_PANEL_MINX 100 #define UI_PANEL_MINY 70 diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index f522af51c42..28e361ccf5a 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -1570,8 +1570,6 @@ static void ui_popup_block_clip(wmWindow *window, uiBlock *block) void ui_popup_block_scrolltest(uiBlock *block) { uiBut *bt; - /* Knowing direction is necessary for multi-column menus... */ - int is_flip = (block->direction & UI_TOP) && !(block->flag & UI_BLOCK_NO_FLIP); block->flag &= ~(UI_BLOCK_CLIPBOTTOM | UI_BLOCK_CLIPTOP); @@ -1581,29 +1579,27 @@ void ui_popup_block_scrolltest(uiBlock *block) if (block->buttons.first == block->buttons.last) return; - /* mark buttons that are outside boundary and the ones next to it for arrow(s) */ + /* mark buttons that are outside boundary */ for (bt = block->buttons.first; bt; bt = bt->next) { if (bt->rect.ymin < block->rect.ymin) { bt->flag |= UI_SCROLLED; block->flag |= UI_BLOCK_CLIPBOTTOM; - /* make space for arrow */ - if (bt->rect.ymax < block->rect.ymin + 10) { - if (is_flip && bt->next && bt->next->rect.ymin > bt->rect.ymin) - bt->next->flag |= UI_SCROLLED; - else if (!is_flip && bt->prev && bt->prev->rect.ymin > bt->rect.ymin) - bt->prev->flag |= UI_SCROLLED; - } } if (bt->rect.ymax > block->rect.ymax) { bt->flag |= UI_SCROLLED; block->flag |= UI_BLOCK_CLIPTOP; - /* make space for arrow */ - if (bt->rect.ymin > block->rect.ymax - 10) { - if (!is_flip && bt->next && bt->next->rect.ymax < bt->rect.ymax) - bt->next->flag |= UI_SCROLLED; - else if (is_flip && bt->prev && bt->prev->rect.ymax < bt->rect.ymax) - bt->prev->flag |= UI_SCROLLED; - } + } + } + + /* mark buttons overlapping arrows, if we have them */ + for (bt = block->buttons.first; bt; bt = bt->next) { + if (block->flag & UI_BLOCK_CLIPBOTTOM) { + if (bt->rect.ymin < block->rect.ymin + UI_MENU_SCROLL_ARROW) + bt->flag |= UI_SCROLLED; + } + if (block->flag & UI_BLOCK_CLIPTOP) { + if (bt->rect.ymax > block->rect.ymax - UI_MENU_SCROLL_ARROW) + bt->flag |= UI_SCROLLED; } } } diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index 238024a0856..f41abce947e 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -2000,7 +2000,7 @@ static void ui_draw_but_HSVCIRCLE(uiBut *but, uiWidgetColors *wcol, const rcti * /* draws in resolution of 20x4 colors */ void ui_draw_gradient(rcti *rect, const float hsv[3], const int type, const float alpha) { - const float color_step = (type == UI_GRAD_H) ? 0.02 : 0.05f; + const float color_step = (type == UI_GRAD_H) ? 0.02f : 0.05f; int a; float h = hsv[0], s = hsv[1], v = hsv[2]; float dx, dy, sx1, sx2, sy; @@ -2668,7 +2668,7 @@ static void widget_menubut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), widgetbase_draw(&wtb, wcol); /* text space, arrows are about 0.6 height of button */ - rect->xmax -= (6*BLI_rcti_size_y(rect))/10; + rect->xmax -= (6 * BLI_rcti_size_y(rect)) / 10; } static void widget_menuiconbut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign) diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c index fb7a2615583..f1a3f59bc22 100644 --- a/source/blender/editors/interface/view2d.c +++ b/source/blender/editors/interface/view2d.c @@ -599,7 +599,7 @@ void UI_view2d_curRect_validate_resize(View2D *v2d, int resize) if ((cur->xmin < tot->xmin) && (cur->xmax > tot->xmax)) { /* outside boundaries on both sides, so take middle-point of tot, and place in balanced way */ temp = BLI_rctf_cent_x(tot); - diff = curheight * 0.5f; + diff = curwidth * 0.5f; cur->xmin = temp - diff; cur->xmax = temp + diff; diff --git a/source/blender/editors/mask/mask_draw.c b/source/blender/editors/mask/mask_draw.c index 1c23df1c11e..74cdf4c2a11 100644 --- a/source/blender/editors/mask/mask_draw.c +++ b/source/blender/editors/mask/mask_draw.c @@ -479,7 +479,7 @@ static void draw_spline_curve(const bContext *C, MaskLayer *masklay, MaskSpline (void)draw_type; } -static void draw_masklays(const bContext *C, Mask *mask, const char draw_flag,const char draw_type, +static void draw_masklays(const bContext *C, Mask *mask, const char draw_flag, const char draw_type, int width, int height) { MaskLayer *masklay; diff --git a/source/blender/editors/mesh/CMakeLists.txt b/source/blender/editors/mesh/CMakeLists.txt index 417cf92c29f..c51d2cfb2e5 100644 --- a/source/blender/editors/mesh/CMakeLists.txt +++ b/source/blender/editors/mesh/CMakeLists.txt @@ -74,7 +74,7 @@ if(WITH_INTERNATIONAL) endif() if(WITH_BULLET) - add_definitions(-DWITH_BULLET) + add_definitions(-DWITH_BULLET) endif() blender_add_lib(bf_editor_mesh "${SRC}" "${INC}" "${INC_SYS}") diff --git a/source/blender/editors/mesh/editface.c b/source/blender/editors/mesh/editface.c index 429b2148894..4350c005f95 100644 --- a/source/blender/editors/mesh/editface.c +++ b/source/blender/editors/mesh/editface.c @@ -85,7 +85,7 @@ void paintface_flush_flags(Object *ob) * - Final derived polys => Final derived tessfaces */ - if ((index_array = CustomData_get_layer(&me->fdata, CD_POLYINDEX))) { + if ((index_array = CustomData_get_layer(&me->fdata, CD_ORIGINDEX))) { faces = me->mface; totface = me->totface; @@ -109,7 +109,7 @@ void paintface_flush_flags(Object *ob) } } - if ((index_array = CustomData_get_layer(&dm->faceData, CD_POLYINDEX))) { + if ((index_array = CustomData_get_layer(&dm->faceData, CD_ORIGINDEX))) { polys = dm->getPolyArray(dm); faces = dm->getTessFaceArray(dm); totface = dm->getNumTessFaces(dm); diff --git a/source/blender/editors/mesh/editmesh_bvh.c b/source/blender/editors/mesh/editmesh_bvh.c index e84fa90fe5c..468d0d8d8c6 100644 --- a/source/blender/editors/mesh/editmesh_bvh.c +++ b/source/blender/editors/mesh/editmesh_bvh.c @@ -405,8 +405,7 @@ int BMBVH_EdgeVisible(BMBVHTree *tree, BMEdge *e, ARegion *ar, View3D *v3d, Obje mul_m4_v3(invmat, origin); copy_v3_v3(co1, e->v1->co); - add_v3_v3v3(co2, e->v1->co, e->v2->co); - mul_v3_fl(co2, 0.5f); + mid_v3_v3v3(co2, e->v1->co, e->v2->co); copy_v3_v3(co3, e->v2->co); scale_point(co1, co2, 0.99); diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index 99eee19f66d..3e985a9779c 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -671,6 +671,13 @@ static int unified_findnearest(ViewContext *vc, BMVert **r_eve, BMEdge **r_eed, } /* **************** SIMILAR "group" SELECTS. FACE, EDGE AND VERTEX ************** */ +static EnumPropertyItem prop_similar_compare_types[] = { + {SIM_CMP_EQ, "EQUAL", 0, "Equal", ""}, + {SIM_CMP_GT, "GREATER", 0, "Greater", ""}, + {SIM_CMP_LT, "LESS", 0, "Less", ""}, + + {0, NULL, 0, NULL, NULL} +}; static EnumPropertyItem prop_similar_types[] = { {SIMVERT_NORMAL, "NORMAL", 0, "Normal", ""}, @@ -691,6 +698,7 @@ static EnumPropertyItem prop_similar_types[] = { {SIMFACE_MATERIAL, "MATERIAL", 0, "Material", ""}, {SIMFACE_IMAGE, "IMAGE", 0, "Image", ""}, {SIMFACE_AREA, "AREA", 0, "Area", ""}, + {SIMFACE_SIDES, "SIDES", 0, "Polygon Sides", ""}, {SIMFACE_PERIMETER, "PERIMETER", 0, "Perimeter", ""}, {SIMFACE_NORMAL, "NORMAL", 0, "Normal", ""}, {SIMFACE_COPLANAR, "COPLANAR", 0, "Co-planar", ""}, @@ -708,11 +716,14 @@ static int similar_face_select_exec(bContext *C, wmOperator *op) BMOperator bmop; /* get the type from RNA */ - int type = RNA_enum_get(op->ptr, "type"); - float thresh = RNA_float_get(op->ptr, "threshold"); + const int type = RNA_enum_get(op->ptr, "type"); + const float thresh = RNA_float_get(op->ptr, "threshold"); + const int compare = RNA_enum_get(op->ptr, "compare"); /* initialize the bmop using EDBM api, which does various ui error reporting and other stuff */ - EDBM_op_init(em, &bmop, op, "similar_faces faces=%hf type=%i thresh=%f", BM_ELEM_SELECT, type, thresh); + EDBM_op_init(em, &bmop, op, + "similar_faces faces=%hf type=%i thresh=%f compare=%i", + BM_ELEM_SELECT, type, thresh, compare); /* execute the operator */ BMO_op_exec(em->bm, &bmop); @@ -746,11 +757,14 @@ static int similar_edge_select_exec(bContext *C, wmOperator *op) BMOperator bmop; /* get the type from RNA */ - int type = RNA_enum_get(op->ptr, "type"); - float thresh = RNA_float_get(op->ptr, "threshold"); + const int type = RNA_enum_get(op->ptr, "type"); + const float thresh = RNA_float_get(op->ptr, "threshold"); + const int compare = RNA_enum_get(op->ptr, "compare"); /* initialize the bmop using EDBM api, which does various ui error reporting and other stuff */ - EDBM_op_init(em, &bmop, op, "similar_edges edges=%he type=%i thresh=%f", BM_ELEM_SELECT, type, thresh); + EDBM_op_init(em, &bmop, op, + "similar_edges edges=%he type=%i thresh=%f compare=%i", + BM_ELEM_SELECT, type, thresh, compare); /* execute the operator */ BMO_op_exec(em->bm, &bmop); @@ -787,11 +801,14 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op) BMEditMesh *em = BMEdit_FromObject(ob); BMOperator bmop; /* get the type from RNA */ - int type = RNA_enum_get(op->ptr, "type"); + const int type = RNA_enum_get(op->ptr, "type"); float thresh = RNA_float_get(op->ptr, "threshold"); + const int compare = RNA_enum_get(op->ptr, "compare"); /* initialize the bmop using EDBM api, which does various ui error reporting and other stuff */ - EDBM_op_init(em, &bmop, op, "similar_verts verts=%hv type=%i thresh=%f", BM_ELEM_SELECT, type, thresh); + EDBM_op_init(em, &bmop, op, + "similar_verts verts=%hv type=%i thresh=%f compare=%i", + BM_ELEM_SELECT, type, thresh, compare); /* execute the operator */ BMO_op_exec(em->bm, &bmop); @@ -820,7 +837,7 @@ static int edbm_select_similar_exec(bContext *C, wmOperator *op) ToolSettings *ts = CTX_data_tool_settings(C); PropertyRNA *prop = RNA_struct_find_property(op->ptr, "threshold"); - int type = RNA_enum_get(op->ptr, "type"); + const int type = RNA_enum_get(op->ptr, "type"); if (!RNA_property_is_set(op->ptr, prop)) { RNA_property_float_set(op->ptr, prop, ts->select_thresh); @@ -831,7 +848,7 @@ static int edbm_select_similar_exec(bContext *C, wmOperator *op) if (type < 100) return similar_vert_select_exec(C, op); else if (type < 200) return similar_edge_select_exec(C, op); - else return similar_face_select_exec(C, op); + else return similar_face_select_exec(C, op); } static EnumPropertyItem *select_similar_type_itemf(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), @@ -895,7 +912,9 @@ void MESH_OT_select_similar(wmOperatorType *ot) prop = ot->prop = RNA_def_enum(ot->srna, "type", prop_similar_types, SIMVERT_NORMAL, "Type", ""); RNA_def_enum_funcs(prop, select_similar_type_itemf); - RNA_def_float(ot->srna, "threshold", 0.0, 0.0, 1.0, "Threshold", "", 0.01, 1.0); + RNA_def_enum(ot->srna, "compare", prop_similar_compare_types, SIM_CMP_EQ, "Compare", ""); + + RNA_def_float(ot->srna, "threshold", 0.0, 0.0, 1.0, "Threshold", "", 0.0, 1.0); } /* ***************************************************** */ @@ -2299,9 +2318,9 @@ static int edbm_select_nth_exec(bContext *C, wmOperator *op) void MESH_OT_select_nth(wmOperatorType *ot) { /* identifiers */ - ot->name = "Select Nth"; + ot->name = "Checker Deselect"; ot->idname = "MESH_OT_select_nth"; - ot->description = "Select every Nth element starting from a selected vertex, edge or face"; + ot->description = "Deselect every Nth element starting from a selected vertex, edge or face"; /* api callbacks */ ot->exec = edbm_select_nth_exec; diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 9d3cc7b7c76..df22cbcb294 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -3808,30 +3808,36 @@ void MESH_OT_screw(wmOperatorType *ot) "Axis", "Axis in global view space", -1.0f, 1.0f); } -static int edbm_select_by_number_vertices_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); BMFace *efa; BMIter iter; - int numverts = RNA_int_get(op->ptr, "number"); - int type = RNA_enum_get(op->ptr, "type"); + const int numverts = RNA_int_get(op->ptr, "number"); + const int type = RNA_enum_get(op->ptr, "type"); BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { - int select = 0; + int select; - if (type == 0 && efa->len < numverts) { - select = 1; - } - else if (type == 1 && efa->len == numverts) { - select = 1; - } - else if (type == 2 && efa->len > numverts) { - select = 1; - } - else if (type == 3 && efa->len != numverts) { - select = 1; + 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) { @@ -3845,7 +3851,7 @@ static int edbm_select_by_number_vertices_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -void MESH_OT_select_by_number_vertices(wmOperatorType *ot) +void MESH_OT_select_face_by_sides(wmOperatorType *ot) { static const EnumPropertyItem type_items[] = { {0, "LESS", 0, "Less Than", ""}, @@ -3856,12 +3862,12 @@ void MESH_OT_select_by_number_vertices(wmOperatorType *ot) }; /* identifiers */ - ot->name = "Select by Number of Vertices"; - ot->description = "Select vertices or faces by vertex count"; - ot->idname = "MESH_OT_select_by_number_vertices"; + 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_by_number_vertices_exec; + ot->exec = edbm_select_face_by_sides_exec; ot->poll = ED_operator_editmesh; /* flags */ diff --git a/source/blender/editors/mesh/mesh_data.c b/source/blender/editors/mesh/mesh_data.c index 4adf37a14c3..e9906f852de 100644 --- a/source/blender/editors/mesh/mesh_data.c +++ b/source/blender/editors/mesh/mesh_data.c @@ -235,7 +235,8 @@ static void delete_customdata_layer(bContext *C, Object *ob, CustomDataLayer *la } } -int ED_mesh_uv_loop_reset_ex(struct bContext *C, struct Mesh *me, const int layernum) +/* without bContext, called in uvedit */ +int ED_mesh_uv_loop_reset_ex(struct Mesh *me, const int layernum) { BMEditMesh *em = me->edit_btmesh; MLoopUV *luv; @@ -338,7 +339,6 @@ int ED_mesh_uv_loop_reset_ex(struct bContext *C, struct Mesh *me, const int laye BLI_array_free(polylengths); DAG_id_tag_update(&me->id, 0); - WM_event_add_notifier(C, NC_GEOM | ND_DATA, me); return 1; } @@ -348,7 +348,11 @@ int ED_mesh_uv_loop_reset(struct bContext *C, struct Mesh *me) /* could be ldata or pdata */ CustomData *pdata = GET_CD_DATA(me, pdata); const int layernum = CustomData_get_active_layer_index(pdata, CD_MTEXPOLY); - return ED_mesh_uv_loop_reset_ex(C, me, layernum); + int retval = ED_mesh_uv_loop_reset_ex(me, layernum); + + WM_event_add_notifier(C, NC_GEOM | ND_DATA, me); + + return retval; } /* note: keep in sync with ED_mesh_color_add */ @@ -419,7 +423,7 @@ int ED_mesh_uv_texture_add(bContext *C, Mesh *me, const char *name, int active_s /* don't overwrite our copied coords */ if (is_init == FALSE) { - ED_mesh_uv_loop_reset_ex(C, me, layernum_dst); + ED_mesh_uv_loop_reset_ex(me, layernum_dst); } DAG_id_tag_update(&me->id, 0); @@ -902,7 +906,7 @@ void ED_mesh_update(Mesh *mesh, bContext *C, int calc_edges, int calc_tessface) * so rather then add poly-index layer and calculate normals for it * calculate normals only for the mvert's. - campbell */ #ifdef USE_BMESH_MPOLY_NORMALS - polyindex = CustomData_get_layer(&mesh->fdata, CD_POLYINDEX); + polyindex = CustomData_get_layer(&mesh->fdata, CD_ORIGINDEX); /* add a normals layer for tessellated faces, a tessface normal will * contain the normal of the poly the face was tessellated from. */ face_nors = CustomData_add_layer(&mesh->fdata, CD_NORMAL, CD_CALLOC, NULL, mesh->totface); @@ -947,6 +951,7 @@ static void mesh_add_verts(Mesh *mesh, int len) /* scan the input list and insert the new vertices */ + /* set default flags */ mvert = &mesh->mvert[mesh->totvert]; for (i = 0; i < len; i++, mvert++) mvert->flag |= SELECT; diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h index 65701663df4..881e4bc02e2 100644 --- a/source/blender/editors/mesh/mesh_intern.h +++ b/source/blender/editors/mesh/mesh_intern.h @@ -121,7 +121,7 @@ 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_by_number_vertices(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); diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c index 64e61d436ee..4036e0c6822 100644 --- a/source/blender/editors/mesh/mesh_ops.c +++ b/source/blender/editors/mesh/mesh_ops.c @@ -68,7 +68,7 @@ void ED_operatortypes_mesh(void) WM_operatortype_append(MESH_OT_select_random); WM_operatortype_append(MESH_OT_hide); WM_operatortype_append(MESH_OT_reveal); - WM_operatortype_append(MESH_OT_select_by_number_vertices); + WM_operatortype_append(MESH_OT_select_face_by_sides); WM_operatortype_append(MESH_OT_select_loose_verts); WM_operatortype_append(MESH_OT_select_mirror); WM_operatortype_append(MESH_OT_normals_make_consistent); diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c index 765f9307247..c0b6327d740 100644 --- a/source/blender/editors/mesh/meshtools.c +++ b/source/blender/editors/mesh/meshtools.c @@ -299,12 +299,12 @@ int join_mesh_exec(bContext *C, wmOperator *op) /* setup new data for destination mesh */ - memset(&vdata, 0, sizeof(vdata)); - memset(&edata, 0, sizeof(edata)); - memset(&fdata, 0, sizeof(fdata)); - memset(&ldata, 0, sizeof(ldata)); - memset(&pdata, 0, sizeof(pdata)); - + CustomData_reset(&vdata); + CustomData_reset(&edata); + CustomData_reset(&fdata); + CustomData_reset(&ldata); + CustomData_reset(&pdata); + mvert = CustomData_add_layer(&vdata, CD_MVERT, CD_CALLOC, NULL, totvert); medge = CustomData_add_layer(&edata, CD_MEDGE, CD_CALLOC, NULL, totedge); mloop = CustomData_add_layer(&ldata, CD_MLOOP, CD_CALLOC, NULL, totloop); diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c index 2914a1ff673..ee3c66b6eac 100644 --- a/source/blender/editors/object/object_bake.c +++ b/source/blender/editors/object/object_bake.c @@ -150,11 +150,13 @@ typedef struct { float height_min, height_max; Image *ima; DerivedMesh *ssdm; - const int *origindex; + const int *orig_index_mf_to_mpoly; + const int *orig_index_mp_to_orig; } MHeightBakeData; typedef struct { - const int *origindex; + const int *orig_index_mf_to_mpoly; + const int *orig_index_mp_to_orig; } MNormalBakeData; static void multiresbake_get_normal(const MResolvePixelData *data, float norm[], const int face_num, const int vert_index) @@ -508,7 +510,9 @@ static void interp_bilinear_grid(CCGKey *key, CCGElem *grid, float crn_x, float interp_bilinear_quad_data(data, u, v, res); } -static void get_ccgdm_data(DerivedMesh *lodm, DerivedMesh *hidm, const int *origindex, const int lvl, const int face_index, const float u, const float v, float co[3], float n[3]) +static void get_ccgdm_data(DerivedMesh *lodm, DerivedMesh *hidm, + const int *index_mf_to_mpoly, const int *index_mp_to_orig, + const int lvl, const int face_index, const float u, const float v, float co[3], float n[3]) { MFace mface; CCGElem **grid_data; @@ -532,7 +536,7 @@ static void get_ccgdm_data(DerivedMesh *lodm, DerivedMesh *hidm, const int *orig } else { int side = (1 << (lvl - 1)) + 1; - int grid_index = origindex[face_index]; + int grid_index = DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, face_index); int loc_offs = face_index % (1 << (2 * lvl)); int cell_index = loc_offs % ((side - 1) * (side - 1)); int cell_side = (grid_size - 1) / (side - 1); @@ -628,7 +632,8 @@ static void *init_heights_data(MultiresBakeRender *bkr, Image *ima) } } - height_data->origindex = lodm->getTessFaceDataArray(lodm, CD_ORIGINDEX); + height_data->orig_index_mf_to_mpoly = lodm->getTessFaceDataArray(lodm, CD_ORIGINDEX); + height_data->orig_index_mp_to_orig = lodm->getPolyDataArray(lodm, CD_ORIGINDEX); return (void *)height_data; } @@ -640,7 +645,8 @@ static void *init_normal_data(MultiresBakeRender *bkr, Image *UNUSED(ima)) normal_data = MEM_callocN(sizeof(MNormalBakeData), "MultiresBake normalData"); - normal_data->origindex = lodm->getTessFaceDataArray(lodm, CD_ORIGINDEX); + normal_data->orig_index_mf_to_mpoly = lodm->getTessFaceDataArray(lodm, CD_ORIGINDEX); + normal_data->orig_index_mp_to_orig = lodm->getPolyDataArray(lodm, CD_ORIGINDEX); return (void *)normal_data; } @@ -735,10 +741,14 @@ static void apply_heights_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm, CLAMP(uv[0], 0.0f, 1.0f); CLAMP(uv[1], 0.0f, 1.0f); - get_ccgdm_data(lores_dm, hires_dm, height_data->origindex, lvl, face_index, uv[0], uv[1], p1, 0); + get_ccgdm_data(lores_dm, hires_dm, + height_data->orig_index_mf_to_mpoly, height_data->orig_index_mf_to_mpoly, + lvl, face_index, uv[0], uv[1], p1, 0); if (height_data->ssdm) { - get_ccgdm_data(lores_dm, height_data->ssdm, height_data->origindex, 0, face_index, uv[0], uv[1], p0, n); + get_ccgdm_data(lores_dm, height_data->ssdm, + height_data->orig_index_mf_to_mpoly, height_data->orig_index_mf_to_mpoly, + 0, face_index, uv[0], uv[1], p0, n); } else { lores_dm->getTessFace(lores_dm, face_index, &mface); @@ -808,7 +818,9 @@ static void apply_tangmat_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm, CLAMP(uv[0], 0.0f, 1.0f); CLAMP(uv[1], 0.0f, 1.0f); - get_ccgdm_data(lores_dm, hires_dm, normal_data->origindex, lvl, face_index, uv[0], uv[1], NULL, n); + get_ccgdm_data(lores_dm, hires_dm, + normal_data->orig_index_mf_to_mpoly, normal_data->orig_index_mp_to_orig, + lvl, face_index, uv[0], uv[1], NULL, n); mul_v3_m3v3(vec, tangmat, n); normalize_v3(vec); diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index c0f9ecfa5a2..05524af34f0 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -138,21 +138,12 @@ bDeformGroup *ED_vgroup_add(Object *ob) void ED_vgroup_delete(Object *ob, bDeformGroup *defgroup) { - bDeformGroup *dg = (bDeformGroup *)ob->defbase.first; - - while (dg) { - if (dg == defgroup) - break; - dg = dg->next; - } - - if (dg == NULL) - return; + BLI_assert(BLI_findindex(&ob->defbase, defgroup) != -1); if (ED_vgroup_object_is_edit_mode(ob)) - vgroup_delete_edit_mode(ob, dg); + vgroup_delete_edit_mode(ob, defgroup); else - vgroup_delete_object_mode(ob, dg); + vgroup_delete_object_mode(ob, defgroup); } void ED_vgroup_clear(Object *ob) diff --git a/source/blender/editors/physics/physics_fluid.c b/source/blender/editors/physics/physics_fluid.c index 4a313079ad0..9a21595e482 100644 --- a/source/blender/editors/physics/physics_fluid.c +++ b/source/blender/editors/physics/physics_fluid.c @@ -944,8 +944,7 @@ static int fluidsimBake(bContext *C, ReportList *reports, Object *fsDomain, shor if (domainSettings->resolutionxyz>128) { gridlevels = 2; } - else - if (domainSettings->resolutionxyz>64) { + else if (domainSettings->resolutionxyz > 64) { gridlevels = 1; } else { diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c index ad9b082d044..fe802abc3a9 100644 --- a/source/blender/editors/render/render_internal.c +++ b/source/blender/editors/render/render_internal.c @@ -497,8 +497,8 @@ static int screen_render_invoke(bContext *C, wmOperator *op, wmEvent *event) return OPERATOR_CANCELLED; } - /* stop all running jobs, currently previews frustrate Render */ - WM_jobs_stop_all(CTX_wm_manager(C)); + /* stop all running jobs, except screen one. currently previews frustrate Render */ + WM_jobs_kill_all_except(CTX_wm_manager(C), CTX_wm_screen(C)); /* get main */ if (G.debug_value == 101) { diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c index 0b6b5cb8e4a..e4592a4f77e 100644 --- a/source/blender/editors/render/render_opengl.c +++ b/source/blender/editors/render/render_opengl.c @@ -333,8 +333,8 @@ static int screen_opengl_render_init(bContext *C, wmOperator *op) return 0; } - /* stop all running jobs, currently previews frustrate Render */ - WM_jobs_stop_all(CTX_wm_manager(C)); + /* stop all running jobs, except screen one. currently previews frustrate Render */ + WM_jobs_kill_all_except(CTX_wm_manager(C), CTX_wm_screen(C)); /* create offscreen buffer */ sizex = (scene->r.size * scene->r.xsch) / 100; diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index bd171ef247a..6a9c24d2913 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -3156,11 +3156,12 @@ static int screen_animation_step(bContext *C, wmOperator *UNUSED(op), wmEvent *e for (sa = window->screen->areabase.first; sa; sa = sa->next) { ARegion *ar; for (ar = sa->regionbase.first; ar; ar = ar->next) { - if (ar == sad->ar) + if (ar == sad->ar) { ED_region_tag_redraw(ar); - else - if (match_region_with_redraws(sa->spacetype, ar->regiontype, sad->redraws)) + } + else if (match_region_with_redraws(sa->spacetype, ar->regiontype, sad->redraws)) { ED_region_tag_redraw(ar); + } } if (match_area_with_refresh(sa->spacetype, sad->refresh)) diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c index 91a0a3821c9..e00a8776bea 100644 --- a/source/blender/editors/sculpt_paint/paint_image.c +++ b/source/blender/editors/sculpt_paint/paint_image.c @@ -5266,10 +5266,12 @@ static int get_imapaint_zoom(bContext *C, float *zoomx, float *zoomy) if (!rv3d) { SpaceImage *sima = CTX_wm_space_image(C); ARegion *ar = CTX_wm_region(C); - - ED_space_image_get_zoom(sima, ar, zoomx, zoomy); - return 1; + if (sima->mode == SI_MODE_PAINT) { + ED_space_image_get_zoom(sima, ar, zoomx, zoomy); + + return 1; + } } *zoomx = *zoomy = 1; @@ -5290,16 +5292,13 @@ static void brush_drawcursor(bContext *C, int x, int y, void *UNUSED(customdata) Brush *brush = paint_brush(paint); if (paint && brush && paint->flags & PAINT_SHOW_BRUSH) { - ToolSettings *ts; float zoomx, zoomy; const float size = (float)BKE_brush_size_get(scene, brush); short use_zoom; float pixel_size; float alpha = 0.5f; - ts = scene->toolsettings; - use_zoom = get_imapaint_zoom(C, &zoomx, &zoomy) && - !(ts->use_uv_sculpt && (scene->basact->object->mode == OB_MODE_EDIT)); + use_zoom = get_imapaint_zoom(C, &zoomx, &zoomy); if (use_zoom) { pixel_size = size * max_ff(zoomx, zoomy); diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c index b3679516fff..c5eff1a1f0e 100644 --- a/source/blender/editors/sculpt_paint/paint_utils.c +++ b/source/blender/editors/sculpt_paint/paint_utils.c @@ -248,19 +248,25 @@ static void imapaint_tri_weights(Object *ob, void imapaint_pick_uv(Scene *scene, Object *ob, unsigned int faceindex, const int xy[2], float uv[2]) { DerivedMesh *dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH); - const int *index = dm->getTessFaceDataArray(dm, CD_ORIGINDEX); MTFace *tface = dm->getTessFaceDataArray(dm, CD_MTFACE), *tf; int numfaces = dm->getNumTessFaces(dm), a, findex; float p[2], w[3], absw, minabsw; MFace mf; MVert mv[4]; + /* double lookup */ + const int *index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX); + const int *index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX); + if ((index_mf_to_mpoly && index_mp_to_orig) == FALSE) { + index_mf_to_mpoly = index_mp_to_orig = NULL; + } + minabsw = 1e10; uv[0] = uv[1] = 0.0; /* test all faces in the derivedmesh with the original index of the picked face */ for (a = 0; a < numfaces; a++) { - findex = index ? index[a] : a; + findex = index_mf_to_mpoly ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, a) : a; if (findex == faceindex) { dm->getTessFace(dm, a, &mf); diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index b8ac88f4d65..56d46a22e10 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -79,6 +79,7 @@ #include "WM_api.h" #include "WM_types.h" +#include "GPU_buffers.h" #include "ED_armature.h" #include "ED_mesh.h" @@ -106,18 +107,40 @@ static int vertex_paint_use_fast_update_check(Object *ob) /* if the polygons from the mesh and the 'derivedFinal' match * we can assume that no modifiers are applied and that its worth adding tessellated faces * so 'vertex_paint_use_fast_update_check()' returns TRUE */ -static int vertex_paint_use_tessface_check(Object *ob) +static int vertex_paint_use_tessface_check(Object *ob, Mesh *me) { DerivedMesh *dm = ob->derivedFinal; - if (dm) { - Mesh *me = BKE_mesh_from_object(ob); - return (me->mpoly == CustomData_get_layer(&dm->faceData, CD_MPOLY)); + if (me && dm) { + return (me->mpoly == CustomData_get_layer(&dm->polyData, CD_MPOLY)); } return FALSE; } +static void update_tessface_data(Object *ob, Mesh *me) +{ + if (vertex_paint_use_tessface_check(ob, me)) { + /* assume if these exist, that they are up to date & valid */ + if (!me->mcol || !me->mface) { + /* should always be true */ + /* XXX Why this clearing? tessface_calc will reset it anyway! */ +/* if (me->mcol) {*/ +/* memset(me->mcol, 255, 4 * sizeof(MCol) * me->totface);*/ +/* }*/ + + /* create tessfaces because they will be used for drawing & fast updates */ + BKE_mesh_tessface_calc(me); /* does own call to update pointers */ + } + } + else { + if (me->totface) { + /* this wont be used, theres no need to keep it */ + BKE_mesh_tessface_clear(me); + } + } + +} /* polling - retrieve whether cursor should be set or operator should be done */ /* Returns true if vertex paint mode is active */ @@ -331,24 +354,7 @@ static void make_vertexcol(Object *ob) /* single ob */ mesh_update_customdata_pointers(me, TRUE); } - if (vertex_paint_use_tessface_check(ob)) { - /* assume if these exist, that they are up to date & valid */ - if (!me->mcol || !me->mface) { - /* should always be true */ - if (me->mcol) { - memset(me->mcol, 255, 4 * sizeof(MCol) * me->totface); - } - - /* create tessfaces because they will be used for drawing & fast updates */ - BKE_mesh_tessface_calc(me); /* does own call to update pointers */ - } - } - else { - if (me->totface) { - /* this wont be used, theres no need to keep it */ - BKE_mesh_tessface_clear(me); - } - } + update_tessface_data(ob, me); //if (shade) // shadeMeshMCol(scene, ob, me); @@ -2564,7 +2570,7 @@ static void vpaint_build_poly_facemap(struct VPaintData *vd, Mesh *me) vd->polyfacemap = BLI_memarena_alloc(vd->polyfacemap_arena, sizeof(ListBase) * me->totpoly); - origIndex = CustomData_get_layer(&me->fdata, CD_POLYINDEX); + origIndex = CustomData_get_layer(&me->fdata, CD_ORIGINDEX); mf = me->mface; if (!origIndex) @@ -2600,7 +2606,12 @@ static int vpaint_stroke_test_start(bContext *C, struct wmOperator *op, const fl make_vertexcol(ob); if (me->mloopcol == NULL) return OPERATOR_CANCELLED; - + + /* Update tessface data if needed + * Added here too because e.g. switching to/from edit mode would remove tessface data, + * yet "fast_update" could still be used! */ + update_tessface_data(ob, me); + /* make mode data storage */ vpd = MEM_callocN(sizeof(struct VPaintData), "VPaintData"); paint_stroke_set_mode_data(stroke, vpd); @@ -2616,9 +2627,11 @@ static int vpaint_stroke_test_start(bContext *C, struct wmOperator *op, const fl if (vertex_paint_use_fast_update_check(ob)) { vpaint_build_poly_facemap(vpd, me); vpd->use_fast_update = TRUE; +/* printf("Fast update!\n");*/ } else { vpd->use_fast_update = FALSE; +/* printf("No fast update!\n");*/ } /* for filtering */ @@ -2632,14 +2645,6 @@ static int vpaint_stroke_test_start(bContext *C, struct wmOperator *op, const fl return 1; } -static void copy_lcol_to_mcol(MCol *mcol, const MLoopCol *lcol) -{ - mcol->a = lcol->a; - mcol->r = lcol->r; - mcol->g = lcol->g; - mcol->b = lcol->b; -} - static void vpaint_paint_poly(VPaint *vp, VPaintData *vpd, Object *ob, const unsigned int index, const float mval[2], const float brush_size_pressure, const float brush_alpha_pressure) @@ -2707,11 +2712,18 @@ static void vpaint_paint_poly(VPaint *vp, VPaintData *vpd, Object *ob, ml = me->mloop + mpoly->loopstart; mlc = me->mloopcol + mpoly->loopstart; for (j = 0; j < mpoly->totloop; j++, ml++, mlc++) { - if (ml->v == mf->v1) copy_lcol_to_mcol(mc + 0, mlc); - else if (ml->v == mf->v2) copy_lcol_to_mcol(mc + 1, mlc); - else if (ml->v == mf->v3) copy_lcol_to_mcol(mc + 2, mlc); - else if (mf->v4 && ml->v == mf->v4) copy_lcol_to_mcol(mc + 3, mlc); - + if (ml->v == mf->v1) { + MESH_MLOOPCOL_TO_MCOL(mlc, mc + 0); + } + else if (ml->v == mf->v2) { + MESH_MLOOPCOL_TO_MCOL(mlc, mc + 1); + } + else if (ml->v == mf->v3) { + MESH_MLOOPCOL_TO_MCOL(mlc, mc + 2); + } + else if (mf->v4 && ml->v == mf->v4) { + MESH_MLOOPCOL_TO_MCOL(mlc, mc + 3); + } } } } @@ -2792,6 +2804,10 @@ static void vpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P * avoid this if we can! */ DAG_id_tag_update(ob->data, 0); } + else if (!GPU_buffer_legacy(ob->derivedFinal)) { + /* If using new VBO drawing, mark mcol as dirty to force colors gpu buffer refresh! */ + ob->derivedFinal->dirty |= DM_DIRTY_MCOL_UPDATE_DRAW; + } } static void vpaint_stroke_done(const bContext *C, struct PaintStroke *stroke) diff --git a/source/blender/editors/space_console/console_ops.c b/source/blender/editors/space_console/console_ops.c index c2344cca557..d3ae5373a18 100644 --- a/source/blender/editors/space_console/console_ops.c +++ b/source/blender/editors/space_console/console_ops.c @@ -450,7 +450,9 @@ static int console_indent_exec(bContext *C, wmOperator *UNUSED(op)) memmove(ci->line + len, ci->line, ci->len); memset(ci->line, ' ', len); ci->len += len; + BLI_assert(ci->len >= 0); console_line_cursor_set(ci, ci->cursor + len); + console_select_offset(sc, len); console_textview_update_rect(sc, ar); ED_area_tag_redraw(CTX_wm_area(C)); @@ -496,9 +498,10 @@ static int console_unindent_exec(bContext *C, wmOperator *UNUSED(op)) memmove(ci->line, ci->line + len, (ci->len - len) + 1); ci->len -= len; - console_line_cursor_set(ci, ci->cursor - len); + BLI_assert(ci->len >= 0); - //console_select_offset(sc, -4); + console_line_cursor_set(ci, ci->cursor - len); + console_select_offset(sc, -len); console_textview_update_rect(sc, ar); ED_area_tag_redraw(CTX_wm_area(C)); @@ -555,6 +558,7 @@ static int console_delete_exec(bContext *C, wmOperator *op) if (stride) { memmove(ci->line + ci->cursor, ci->line + ci->cursor + stride, (ci->len - ci->cursor) + 1); ci->len -= stride; + BLI_assert(ci->len >= 0); done = TRUE; } } @@ -571,6 +575,7 @@ static int console_delete_exec(bContext *C, wmOperator *op) ci->cursor -= stride; /* same as above */ memmove(ci->line + ci->cursor, ci->line + ci->cursor + stride, (ci->len - ci->cursor) + 1); ci->len -= stride; + BLI_assert(ci->len >= 0); done = TRUE; } } diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c index b505fed7baa..0b5f636cedd 100644 --- a/source/blender/editors/space_file/filelist.c +++ b/source/blender/editors/space_file/filelist.c @@ -785,6 +785,7 @@ static int file_extension_type(const char *relname) } else if (BLI_testextensie(relname, ".txt") || BLI_testextensie(relname, ".glsl") || + BLI_testextensie(relname, ".osl") || BLI_testextensie(relname, ".data")) { return TEXTFILE; diff --git a/source/blender/editors/space_file/fsmenu.c b/source/blender/editors/space_file/fsmenu.c index c57bfaeeb2c..a5647c06b92 100644 --- a/source/blender/editors/space_file/fsmenu.c +++ b/source/blender/editors/space_file/fsmenu.c @@ -367,7 +367,7 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks) FSRefMakePath(&dir, path, FILE_MAX); if (strcmp((char *)path, "/home") && strcmp((char *)path, "/net")) { /* /net and /home are meaningless on OSX, home folders are stored in /Users */ - fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, (char *)path, FS_INSERT_SORTED); + fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, (char *)path, FS_INSERT_SORTED); } } @@ -429,7 +429,7 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks) if (!CFStringGetCString(pathString, line, 256, kCFStringEncodingASCII)) continue; - fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED); + fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, line, FS_INSERT_SORTED); CFRelease(pathString); CFRelease(cfURL); @@ -456,7 +456,10 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks) FSRefMakePath(&dir, path, FILE_MAX); - fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, (char *)path, FS_INSERT_SORTED); + if (strcmp((char *)path, "/home") && strcmp((char *)path, "/net")) { + /* /net and /home are meaningless on OSX, home folders are stored in /Users */ + fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, (char *)path, FS_INSERT_SORTED); + } } /* Finally get user favorite places */ diff --git a/source/blender/editors/space_logic/logic_window.c b/source/blender/editors/space_logic/logic_window.c index bffabe6d160..5a8a7cef119 100644 --- a/source/blender/editors/space_logic/logic_window.c +++ b/source/blender/editors/space_logic/logic_window.c @@ -56,6 +56,7 @@ #include "BKE_library.h" #include "BKE_main.h" #include "BKE_sca.h" +#include "BKE_screen.h" #include "ED_util.h" @@ -66,6 +67,7 @@ #include "BLF_translation.h" #include "UI_interface.h" +#include "UI_view2d.h" #include "RNA_access.h" @@ -2208,15 +2210,13 @@ void logic_buttons(bContext *C, ARegion *ar) SpaceLogic *slogic= CTX_wm_space_logic(C); Object *ob= CTX_data_active_object(C); ID **idar; - PointerRNA logic_ptr, settings_ptr, object_ptr; - uiLayout *layout, *row, *box; uiBlock *block; uiBut *but; char uiblockstr[32]; short a, count; - int xco, yco, width; + int xco, yco, width, height; if (ob==NULL) return; @@ -2270,7 +2270,7 @@ void logic_buttons(bContext *C, ARegion *ar) /* ****************** Controllers ****************** */ - xco= 420; yco= 170; width= 300; + xco= 420; yco= -10; width= 300; layout= uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, xco, yco, width, 20, UI_GetStyle()); row = uiLayoutRow(layout, TRUE); @@ -2373,11 +2373,11 @@ void logic_buttons(bContext *C, ARegion *ar) } } uiBlockLayoutResolve(block, NULL, &yco); /* stores final height in yco */ - + height = yco; /* ****************** Sensors ****************** */ - xco= 10; yco= 170; width= 340; + xco= 10; yco= -10; width= 340; layout= uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, xco, yco, width, 20, UI_GetStyle()); row = uiLayoutRow(layout, TRUE); @@ -2442,10 +2442,11 @@ void logic_buttons(bContext *C, ARegion *ar) } } uiBlockLayoutResolve(block, NULL, &yco); /* stores final height in yco */ + height = MIN2(height, yco); /* ****************** Actuators ****************** */ - xco= 800; yco= 170; width= 340; + xco= 800; yco= -10; width= 340; layout= uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, xco, yco, width, 20, UI_GetStyle()); row = uiLayoutRow(layout, TRUE); @@ -2513,13 +2514,21 @@ void logic_buttons(bContext *C, ARegion *ar) } } uiBlockLayoutResolve(block, NULL, &yco); /* stores final height in yco */ + height = MIN2(height, yco); + + UI_view2d_totRect_set(&ar->v2d, 1150, height); - + /* set the view */ + UI_view2d_view_ortho(&ar->v2d); + uiComposeLinks(block); uiEndBlock(C, block); uiDrawBlock(C, block); + /* restore view matrix */ + UI_view2d_view_restore(C); + if (idar) MEM_freeN(idar); } diff --git a/source/blender/editors/space_logic/space_logic.c b/source/blender/editors/space_logic/space_logic.c index c4ec801d6ed..4cd53215697 100644 --- a/source/blender/editors/space_logic/space_logic.c +++ b/source/blender/editors/space_logic/space_logic.c @@ -84,8 +84,9 @@ ARegion *logic_has_buttons_region(ScrArea *sa) /* ******************** default callbacks for image space ***************** */ -static SpaceLink *logic_new(const bContext *UNUSED(C)) +static SpaceLink *logic_new(const bContext *C) { + ScrArea *sa= CTX_wm_area(C); ARegion *ar; SpaceLogic *slogic; @@ -93,10 +94,10 @@ static SpaceLink *logic_new(const bContext *UNUSED(C)) slogic->spacetype= SPACE_LOGIC; /* default options */ - slogic->scaflag = (BUTS_SENS_SEL|BUTS_SENS_ACT|BUTS_SENS_LINK) | - (BUTS_CONT_SEL|BUTS_CONT_ACT|BUTS_CONT_LINK) | - (BUTS_ACT_SEL|BUTS_ACT_ACT|BUTS_ACT_LINK) | - (BUTS_SENS_STATE|BUTS_ACT_STATE); + slogic->scaflag = ((BUTS_SENS_SEL|BUTS_SENS_ACT|BUTS_SENS_LINK) | + (BUTS_CONT_SEL|BUTS_CONT_ACT|BUTS_CONT_LINK) | + (BUTS_ACT_SEL|BUTS_ACT_ACT|BUTS_ACT_LINK) | + (BUTS_SENS_STATE|BUTS_ACT_STATE)); /* header */ @@ -120,14 +121,11 @@ static SpaceLink *logic_new(const bContext *UNUSED(C)) ar->regiontype= RGN_TYPE_WINDOW; ar->v2d.tot.xmin = 0.0f; - ar->v2d.tot.ymin = 0.0f; - ar->v2d.tot.xmax = 1280; - ar->v2d.tot.ymax = 240.0f; + ar->v2d.tot.ymax = 0.0f; + ar->v2d.tot.xmax = 1150.0f; + ar->v2d.tot.ymin = ( 1150.0f/(float)sa->winx ) * (float)-sa->winy; - ar->v2d.cur.xmin = 0.0f; - ar->v2d.cur.ymin = 0.0f; - ar->v2d.cur.xmax = 1280.0f; - ar->v2d.cur.ymax = 240.0f; + ar->v2d.cur = ar->v2d.tot; ar->v2d.min[0] = 1.0f; ar->v2d.min[1] = 1.0f; @@ -136,12 +134,13 @@ static SpaceLink *logic_new(const bContext *UNUSED(C)) ar->v2d.max[1] = 32000.0f; ar->v2d.minzoom = 0.5f; - ar->v2d.maxzoom = 1.21f; + ar->v2d.maxzoom = 1.5f; ar->v2d.scroll = (V2D_SCROLL_RIGHT | V2D_SCROLL_BOTTOM); - ar->v2d.keepzoom = V2D_LIMITZOOM | V2D_KEEPASPECT; - ar->v2d.keeptot = 0; - + ar->v2d.keepzoom = V2D_KEEPZOOM | V2D_LIMITZOOM | V2D_KEEPASPECT; + ar->v2d.keeptot = V2D_KEEPTOT_BOUNDS; + ar->v2d.align = V2D_ALIGN_NO_POS_Y | V2D_ALIGN_NO_NEG_X; + ar->v2d.keepofs = V2D_KEEPOFS_Y; return (SpaceLink *)slogic; } @@ -183,6 +182,9 @@ static void logic_keymap(struct wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "LOGIC_OT_properties", NKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "LOGIC_OT_links_cut", LEFTMOUSE, KM_PRESS, KM_CTRL, 0); WM_keymap_add_menu(keymap, "LOGIC_MT_logicbricks_add", AKEY, KM_PRESS, KM_SHIFT, 0); + + WM_keymap_add_item(keymap, "VIEW2D_OT_reset", HOMEKEY, KM_PRESS, 0, 0); + } static void logic_refresh(const bContext *UNUSED(C), ScrArea *UNUSED(sa)) @@ -234,7 +236,7 @@ static void logic_main_area_init(wmWindowManager *wm, ARegion *ar) wmKeyMap *keymap; UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_CUSTOM, ar->winx, ar->winy); - + /* own keymaps */ keymap = WM_keymap_find(wm->defaultconf, "Logic Editor", SPACE_LOGIC, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); @@ -259,7 +261,7 @@ static void logic_main_area_draw(const bContext *C, ARegion *ar) UI_view2d_view_restore(C); /* scrollers */ - scrollers= UI_view2d_scrollers_calc(C, v2d, 10, V2D_GRID_CLAMP, V2D_ARG_DUMMY, V2D_ARG_DUMMY); + scrollers= UI_view2d_scrollers_calc(C, v2d, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY); UI_view2d_scrollers_draw(C, v2d, scrollers); UI_view2d_scrollers_free(scrollers); diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 711944809fd..0938562857b 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -1384,11 +1384,39 @@ static void node_shader_buts_glossy(uiLayout *layout, bContext *UNUSED(C), Point uiItemR(layout, ptr, "distribution", 0, "", ICON_NONE); } +static void node_shader_buts_script(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) +{ + uiLayout *row; + + row = uiLayoutRow(layout, FALSE); + uiItemR(row, ptr, "mode", UI_ITEM_R_EXPAND, NULL, ICON_NONE); + + row = uiLayoutRow(layout, TRUE); + + if (RNA_enum_get(ptr, "mode") == NODE_SCRIPT_INTERNAL) + uiItemR(row, ptr, "script", 0, "", ICON_NONE); + else + uiItemR(row, ptr, "filepath", 0, "", ICON_NONE); + + uiItemO(row, "", ICON_FILE_REFRESH, "node.shader_script_update"); +} + +static void node_shader_buts_script_details(uiLayout *layout, bContext *C, PointerRNA *ptr) +{ + uiItemS(layout); + + node_shader_buts_script(layout, C, ptr); + + /* not implemented yet + if(RNA_enum_get(ptr, "mode") == NODE_SCRIPT_EXTERNAL) + uiItemR(layout, ptr, "use_auto_update", 0, NULL, ICON_NONE);*/ +} + /* only once called */ static void node_shader_set_butfunc(bNodeType *ntype) { switch (ntype->type) { - /* case NODE_GROUP: note, typeinfo for group is generated... see "XXX ugly hack" */ + /* case NODE_GROUP: note, typeinfo for group is generated... see "XXX ugly hack" */ case SH_NODE_MATERIAL: case SH_NODE_MATERIAL_EXT: @@ -1467,6 +1495,10 @@ static void node_shader_set_butfunc(bNodeType *ntype) case SH_NODE_BSDF_GLASS: ntype->uifunc = node_shader_buts_glossy; break; + case SH_NODE_SCRIPT: + ntype->uifunc = node_shader_buts_script; + ntype->uifuncbut = node_shader_buts_script_details; + break; } } @@ -2639,7 +2671,7 @@ static void node_composit_buts_trackpos(uiLayout *layout, bContext *C, PointerRN static void node_composit_set_butfunc(bNodeType *ntype) { switch (ntype->type) { - /* case NODE_GROUP: note, typeinfo for group is generated... see "XXX ugly hack" */ + /* case NODE_GROUP: note, typeinfo for group is generated... see "XXX ugly hack" */ case CMP_NODE_IMAGE: ntype->uifunc = node_composit_buts_image; diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index f21f343ea2b..6bf0e9f73e3 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -35,6 +35,7 @@ #include "DNA_material_types.h" #include "DNA_node_types.h" #include "DNA_object_types.h" +#include "DNA_text_types.h" #include "DNA_world_types.h" #include "BLI_math.h" @@ -54,6 +55,7 @@ #include "BKE_scene.h" #include "BKE_texture.h" +#include "RE_engine.h" #include "RE_pipeline.h" @@ -2137,3 +2139,120 @@ void NODE_OT_clipboard_paste(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } + +/* ********************** Shader Script Update ******************/ + +typedef struct ScriptUpdateData { + RenderEngine *engine; + RenderEngineType *type; + + Text *text; + int found; +} ScriptUpdateData; + +static int node_shader_script_update_poll(bContext *C) +{ + Scene *scene = CTX_data_scene(C); + RenderEngineType *type = RE_engines_find(scene->r.engine); + bNode *node; + Text *text; + + /* test if we have a render engine that supports shaders scripts */ + if (!(type && type->update_script_node)) + return 0; + + /* see if we have a shader script node in context */ + node = CTX_data_pointer_get_type(C, "node", &RNA_ShaderNodeScript).data; + if (node && node->type == SH_NODE_SCRIPT) { + NodeShaderScript *nss = node->storage; + + if (node->id || nss->filepath[0]) { + return 1; + } + } + + /* see if we have a text datablock in context */ + text = CTX_data_pointer_get_type(C, "edit_text", &RNA_Text).data; + if (text) + return 1; + + /* we don't check if text datablock is actually in use, too slow for poll */ + + return 0; +} + +static void node_shader_script_update_text(void *data_, ID *UNUSED(id), bNodeTree *ntree) +{ + ScriptUpdateData *data = (ScriptUpdateData *)data_; + bNode *node; + + /* update each script that is using this text datablock */ + for (node = ntree->nodes.first; node; node = node->next) { + if (node->type == NODE_GROUP) { + node_shader_script_update_text(data_, NULL, (bNodeTree *)node->id); + } + else if (node->type == SH_NODE_SCRIPT && node->id == &data->text->id) { + data->type->update_script_node(data->engine, ntree, node); + data->found = TRUE; + } + } +} + +static int node_shader_script_update_exec(bContext *C, wmOperator *op) +{ + Main *bmain = CTX_data_main(C); + Scene *scene = CTX_data_scene(C); + ScriptUpdateData data; + PointerRNA nodeptr = CTX_data_pointer_get_type(C, "node", &RNA_ShaderNodeScript); + + /* setup render engine */ + data.type = RE_engines_find(scene->r.engine); + data.engine = RE_engine_create(data.type); + data.engine->reports = op->reports; + data.text = NULL; + data.found = FALSE; + + if (nodeptr.data) { + /* update single node */ + bNodeTree *ntree = nodeptr.id.data; + bNode *node = nodeptr.data; + + data.type->update_script_node(data.engine, ntree, node); + + data.found = TRUE; + } + else { + /* update all nodes using text datablock */ + data.text = CTX_data_pointer_get_type(C, "edit_text", &RNA_Text).data; + + if (data.text) { + bNodeTreeType *ntreetype = ntreeGetType(NTREE_SHADER); + + if (ntreetype && ntreetype->foreach_nodetree) + ntreetype->foreach_nodetree(bmain, &data, node_shader_script_update_text); + + if (!data.found) + BKE_report(op->reports, RPT_INFO, "Text not used by any node, no update done."); + } + } + + RE_engine_free(data.engine); + + return (data.found)? OPERATOR_FINISHED: OPERATOR_CANCELLED; +} + +void NODE_OT_shader_script_update(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Script Node Update"; + ot->description = "Update shader script node with new sockets and options from the script"; + ot->idname = "NODE_OT_shader_script_update"; + + /* api callbacks */ + ot->exec = node_shader_script_update_exec; + ot->poll = node_shader_script_update_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h index 36ebddc8d22..45509e02226 100644 --- a/source/blender/editors/space_node/node_intern.h +++ b/source/blender/editors/space_node/node_intern.h @@ -206,6 +206,8 @@ void NODE_OT_output_file_move_active_socket(struct wmOperatorType *ot); void NODE_OT_clipboard_copy(struct wmOperatorType *ot); void NODE_OT_clipboard_paste(struct wmOperatorType *ot); +void NODE_OT_shader_script_update(struct wmOperatorType *ot); + extern const char *node_context_dir[]; // XXXXXX diff --git a/source/blender/editors/space_node/node_ops.c b/source/blender/editors/space_node/node_ops.c index 560ef9e8a29..64e5f67a348 100644 --- a/source/blender/editors/space_node/node_ops.c +++ b/source/blender/editors/space_node/node_ops.c @@ -117,6 +117,8 @@ void node_operatortypes(void) WM_operatortype_append(NODE_OT_clipboard_copy); WM_operatortype_append(NODE_OT_clipboard_paste); + + WM_operatortype_append(NODE_OT_shader_script_update); } void ED_operatormacros_node(void) diff --git a/source/blender/editors/space_node/node_templates.c b/source/blender/editors/space_node/node_templates.c index d4df449a41b..23f4e948794 100644 --- a/source/blender/editors/space_node/node_templates.c +++ b/source/blender/editors/space_node/node_templates.c @@ -292,8 +292,7 @@ static void ui_node_sock_name(bNodeSocket *sock, char name[UI_MAX_NAME_STR]) BLI_strncpy(node_name, node->typeinfo->name, UI_MAX_NAME_STR); if (node->inputs.first == NULL && - node->outputs.first != node->outputs.last && - !(node->typeinfo->flag & NODE_OPTIONS)) + node->outputs.first != node->outputs.last) { BLI_snprintf(name, UI_MAX_NAME_STR, "%s | %s", IFACE_(node_name), IFACE_(sock->link->fromsock->name)); } diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c index 5fb9780c700..3b83279e09d 100644 --- a/source/blender/editors/space_outliner/outliner_tools.c +++ b/source/blender/editors/space_outliner/outliner_tools.c @@ -158,11 +158,16 @@ static void unlink_material_cb(bContext *UNUSED(C), Scene *UNUSED(scene), TreeEl totcol = mb->totcol; matar = mb->mat; } + else { + BLI_assert(0); + } - for (a = 0; a < totcol; a++) { - if (a == te->index && matar[a]) { - matar[a]->id.us--; - matar[a] = NULL; + if (LIKELY(matar != NULL)) { + for (a = 0; a < totcol; a++) { + if (a == te->index && matar[a]) { + matar[a]->id.us--; + matar[a] = NULL; + } } } } diff --git a/source/blender/editors/space_sequencer/sequencer_select.c b/source/blender/editors/space_sequencer/sequencer_select.c index c4df89547ef..192f45ac918 100644 --- a/source/blender/editors/space_sequencer/sequencer_select.c +++ b/source/blender/editors/space_sequencer/sequencer_select.c @@ -414,8 +414,7 @@ static int sequencer_select_invoke(bContext *C, wmOperator *op, wmEvent *event) BLI_strncpy(ed->act_imagedir, seq->strip->dir, FILE_MAXDIR); } } - else - if (seq->type == SEQ_TYPE_SOUND_RAM) { + else if (seq->type == SEQ_TYPE_SOUND_RAM) { if (seq->strip) { BLI_strncpy(ed->act_sounddir, seq->strip->dir, FILE_MAXDIR); } diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 27a660eac2b..d46eb51f2c5 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -132,7 +132,8 @@ typedef struct drawDMFacesSel_userData { BMEditMesh *em; /* BMESH BRANCH ONLY */ BMFace *efa_act; - int *orig_index; + int *orig_index_mf_to_mpoly; + int *orig_index_mp_to_orig; } drawDMFacesSel_userData; typedef struct drawDMNormal_userData { @@ -233,12 +234,13 @@ static int check_alpha_pass(Base *base) } /***/ -static unsigned int colortab[24] = -{0x0, 0xFF88FF, 0xFFBBFF, - 0x403000, 0xFFFF88, 0xFFFFBB, - 0x104040, 0x66CCCC, 0x77CCCC, - 0x104010, 0x55BB55, 0x66FF66, - 0xFFFFFF}; +static unsigned int colortab[24] = { + 0x0, 0xFF88FF, 0xFFBBFF, + 0x403000, 0xFFFF88, 0xFFFFBB, + 0x104040, 0x66CCCC, 0x77CCCC, + 0x104010, 0x55BB55, 0x66FF66, + 0xFFFFFF +}; static float cube[8][3] = { @@ -2325,11 +2327,11 @@ static int draw_dm_faces_sel__compareDrawOptions(void *userData, int index, int unsigned char *col, *next_col; - if (!data->orig_index) + if (!data->orig_index_mf_to_mpoly) return 0; - efa = EDBM_face_at_index(data->em, data->orig_index[index]); - next_efa = EDBM_face_at_index(data->em, data->orig_index[next_index]); + efa = EDBM_face_at_index(data->em, DM_origindex_mface_mpoly(data->orig_index_mf_to_mpoly, data->orig_index_mp_to_orig, index)); + next_efa = EDBM_face_at_index(data->em, DM_origindex_mface_mpoly(data->orig_index_mf_to_mpoly, data->orig_index_mp_to_orig, next_index)); if (efa == next_efa) return 1; @@ -2358,7 +2360,12 @@ static void draw_dm_faces_sel(BMEditMesh *em, DerivedMesh *dm, unsigned char *ba data.cols[2] = markCol; data.cols[3] = actCol; data.efa_act = efa_act; - data.orig_index = DM_get_tessface_data_layer(dm, CD_ORIGINDEX); + /* double lookup */ + data.orig_index_mf_to_mpoly = DM_get_tessface_data_layer(dm, CD_ORIGINDEX); + data.orig_index_mp_to_orig = DM_get_poly_data_layer(dm, CD_ORIGINDEX); + if ((data.orig_index_mf_to_mpoly && data.orig_index_mp_to_orig) == FALSE) { + data.orig_index_mf_to_mpoly = data.orig_index_mp_to_orig = NULL; + } dm->drawMappedFaces(dm, draw_dm_faces_sel__setDrawOptions, GPU_enable_material, draw_dm_faces_sel__compareDrawOptions, &data, 0); } diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index d61ba5f1181..0a282a17f74 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -1216,13 +1216,13 @@ static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d) if (ca->flag & CAM_SHOWTITLESAFE) { UI_ThemeColorBlendShade(TH_WIRE, TH_BACK, 0.25, 0); - hmargin = 0.1 * (x2 - x1); - vmargin = 0.05 * (y2 - y1); - uiDrawBox(GL_LINE_LOOP, x1+hmargin, y1+vmargin, x2-hmargin, y2-vmargin, 2.0); + hmargin = 0.1f * (x2 - x1); + vmargin = 0.05f * (y2 - y1); + uiDrawBox(GL_LINE_LOOP, x1 + hmargin, y1+vmargin, x2 - hmargin, y2 - vmargin, 2.0f); - hmargin = 0.035 * (x2 - x1); - vmargin = 0.035 * (y2 - y1); - uiDrawBox(GL_LINE_LOOP, x1+hmargin, y1+vmargin, x2-hmargin, y2-vmargin, 2.0); + hmargin = 0.035f * (x2 - x1); + vmargin = 0.035f * (y2 - y1); + uiDrawBox(GL_LINE_LOOP, x1 + hmargin, y1+vmargin, x2 - hmargin, y2 - vmargin, 2.0f); } if (ca && (ca->flag & CAM_SHOWSENSOR)) { /* determine sensor fit, and get sensor x/y, for auto fit we diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 242a3327b78..36d7341f2f2 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -2204,8 +2204,8 @@ static void view3d_from_minmax(bContext *C, View3D *v3d, ARegion *ar, } } - add_v3_v3v3(new_ofs, min, max); - mul_v3_fl(new_ofs, -0.5f); + mid_v3_v3v3(new_ofs, min, max); + negate_v3(new_ofs); new_dist = size; diff --git a/source/blender/editors/space_view3d/view3d_project.c b/source/blender/editors/space_view3d/view3d_project.c index 5362f0377c3..6ba05abae9a 100644 --- a/source/blender/editors/space_view3d/view3d_project.c +++ b/source/blender/editors/space_view3d/view3d_project.c @@ -163,8 +163,8 @@ eV3DProjStatus ED_view3d_project_short_ex(ARegion *ar, float perspmat[4][4], con float tvec[2]; eV3DProjStatus ret = ed_view3d_project__internal(ar, perspmat, is_local, co, tvec, flag); if (ret == V3D_PROJ_RET_OK) { - if ((tvec[0] > -32700.0 && tvec[0] < 32700.0f) && - (tvec[1] > -32700.0 && tvec[1] < 32700.0f)) + if ((tvec[0] > -32700.0f && tvec[0] < 32700.0f) && + (tvec[1] > -32700.0f && tvec[1] < 32700.0f)) { r_co[0] = (short)floor(tvec[0]); r_co[1] = (short)floor(tvec[1]); @@ -182,8 +182,8 @@ eV3DProjStatus ED_view3d_project_int_ex(ARegion *ar, float perspmat[4][4], const float tvec[2]; eV3DProjStatus ret = ed_view3d_project__internal(ar, perspmat, is_local, co, tvec, flag); if (ret == V3D_PROJ_RET_OK) { - if ((tvec[0] > -2140000000.0 && tvec[0] < 2140000000.0f) && - (tvec[1] > -2140000000.0 && tvec[1] < 2140000000.0f)) + if ((tvec[0] > -2140000000.0f && tvec[0] < 2140000000.0f) && + (tvec[1] > -2140000000.0f && tvec[1] < 2140000000.0f)) { r_co[0] = (int)floor(tvec[0]); r_co[1] = (int)floor(tvec[1]); diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 1537b4f61ce..76296b6d3e0 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -4793,8 +4793,7 @@ static BMLoop *get_next_loop(BMVert *v, BMLoop *l, cross_v3_v3v3(a, f2, l->f->no); mul_v3_fl(a, -1.0f); - add_v3_v3(a, f3); - mul_v3_fl(a, 0.5f); + mid_v3_v3v3(a, a, f3); } copy_v3_v3(vec, a); diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 53cedc78d5c..2a01b03ec14 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -130,9 +130,9 @@ static int trans_data_compare_dist(const void *A, const void *B) const TransData *td_A = (const TransData*)A; const TransData *td_B = (const TransData*)B; - if(td_A->dist < td_B->dist) + if (td_A->dist < td_B->dist) return -1; - else if(td_A->dist > td_B->dist) + else if (td_A->dist > td_B->dist) return 1; return 0; @@ -143,9 +143,9 @@ static int trans_data_compare_rdist(const void *A, const void *B) const TransData *td_A = (const TransData*)A; const TransData *td_B = (const TransData*)B; - if(td_A->rdist < td_B->rdist) + if (td_A->rdist < td_B->rdist) return -1; - else if(td_A->rdist > td_B->rdist) + else if (td_A->rdist > td_B->rdist) return 1; return 0; @@ -318,12 +318,8 @@ static void createTransEdge(TransInfo *t) BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) { if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN) && (BM_elem_flag_test(eed, BM_ELEM_SELECT) || propmode)) { - float *bweight = CustomData_bmesh_get(&em->bm->edata, eed->head.data, CD_BWEIGHT); - float *crease = CustomData_bmesh_get(&em->bm->edata, eed->head.data, CD_CREASE); - /* need to set center for center calculations */ - add_v3_v3v3(td->center, eed->v1->co, eed->v2->co); - mul_v3_fl(td->center, 0.5f); + mid_v3_v3v3(td->center, eed->v1->co, eed->v2->co); td->loc = NULL; if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) @@ -331,16 +327,18 @@ static void createTransEdge(TransInfo *t) else td->flag = 0; - copy_m3_m3(td->smtx, smtx); copy_m3_m3(td->mtx, mtx); td->ext = NULL; if (t->mode == TFM_BWEIGHT) { + float *bweight = CustomData_bmesh_get(&em->bm->edata, eed->head.data, CD_BWEIGHT); td->val = bweight; td->ival = bweight ? *bweight : 1.0f; } else { + float *crease = CustomData_bmesh_get(&em->bm->edata, eed->head.data, CD_CREASE); + BLI_assert(t->mode == TFM_CREASE); td->val = crease; td->ival = crease ? *crease : 0.0f; } diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index f550cb05a8b..615bb786071 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -1568,9 +1568,8 @@ void calculateCenterBound(TransInfo *t) copy_v3_v3(min, t->data[i].center); } } - add_v3_v3v3(t->center, min, max); - mul_v3_fl(t->center, 0.5); - + mid_v3_v3v3(t->center, min, max); + calculateCenter2D(t); } @@ -1712,7 +1711,7 @@ void calculatePropRatio(TransInfo *t) /* * The elements are sorted according to their dist member in the array, * that means we can stop when it finds one element outside of the propsize. - * do not set td->flag |= TD_NOACTION , the prop circle is being changed. + * do not set 'td->flag |= TD_NOACTION', the prop circle is being changed. */ td->factor = 0.0f; diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index baca4629883..a6fb7e7ed00 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -78,8 +78,6 @@ #include "transform.h" -#define USE_BVH_FACE_SNAP - #define TRANSFORM_DIST_MAX_PX 1000 /********************* PROTOTYPES ***********************/ @@ -1136,58 +1134,6 @@ static void TargetSnapClosest(TransInfo *t) t->tsnap.status |= TARGET_INIT; } } -/*================================================================*/ -#ifndef USE_BVH_FACE_SNAP -static int snapFace(ARegion *ar, float v1co[3], float v2co[3], float v3co[3], float *v4co, float mval[2], float ray_start[3], float ray_start_local[3], float ray_normal_local[3], float obmat[][4], float timat[][3], float loc[3], float no[3], int *dist, float *depth) -{ - float lambda; - int result; - int retval = 0; - - result = isect_ray_tri_threshold_v3(ray_start_local, ray_normal_local, v1co, v2co, v3co, &lambda, NULL, 0.001); - - if (result) { - float location[3], normal[3]; - float intersect[3]; - float new_depth; - int screen_loc[2]; - int new_dist; - - copy_v3_v3(intersect, ray_normal_local); - mul_v3_fl(intersect, lambda); - add_v3_v3(intersect, ray_start_local); - - copy_v3_v3(location, intersect); - - if (v4co) - normal_quad_v3(normal, v1co, v2co, v3co, v4co); - else - normal_tri_v3(normal, v1co, v2co, v3co); - - mul_m4_v3(obmat, location); - - new_depth = len_v3v3(location, ray_start); - - ED_view3d_project_int(ar, location, screen_loc); - new_dist = abs(screen_loc[0] - (int)mval[0]) + abs(screen_loc[1] - (int)mval[1]); - - if (new_dist <= *dist && new_depth < *depth) { - *depth = new_depth; - retval = 1; - - copy_v3_v3(loc, location); - copy_v3_v3(no, normal); - - mul_m3_v3(timat, no); - normalize_v3(no); - - *dist = new_dist; - } - } - - return retval; -} -#endif static int snapEdge(ARegion *ar, float v1co[3], short v1no[3], float v2co[3], short v2no[3], float obmat[][4], float timat[][3], const float ray_start[3], const float ray_start_local[3], const float ray_normal_local[3], const float mval[2], @@ -1426,7 +1372,6 @@ static int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh switch (snap_mode) { case SCE_SNAP_MODE_FACE: { -#ifdef USE_BVH_FACE_SNAP // Added for durian BVHTreeRayHit hit; BVHTreeFromMesh treeData; @@ -1456,80 +1401,6 @@ static int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh } } break; - -#else - MVert *verts = dm->getVertArray(dm); - MFace *faces = dm->getTessFaceArray(dm); - int *index_array = NULL; - int index = 0; - int i; - - if (em != NULL) { - index_array = dm->getTessFaceDataArray(dm, CD_ORIGINDEX); - EDBM_index_arrays_init(em, 0, 0, 1); - } - - for (i = 0; i < totface; i++) { - BMFace *efa = NULL; - MFace *f = faces + i; - - test = 1; /* reset for every face */ - - if (em != NULL) { - if (index_array) { - index = index_array[i]; - } - else { - index = i; - } - - if (index == ORIGINDEX_NONE) { - test = 0; - } - else { - efa = EDBM_face_at_index(em, index); - - if (efa && BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { - test = 0; - } - else if (efa) { - BMIter iter; - BMLoop *l; - - l = BM_iter_new(&iter, em->bm, BM_LOOPS_OF_FACE, efa); - for (; l; l = BM_iter_step(&iter)) { - if (BM_elem_flag_test(l->v, BM_ELEM_SELECT)) { - test = 0; - break; - } - } - } - } - } - - - if (test) { - int result; - float *v4co = NULL; - - if (f->v4) { - v4co = verts[f->v4].co; - } - - result = snapFace(ar, verts[f->v1].co, verts[f->v2].co, verts[f->v3].co, v4co, mval, ray_start, ray_start_local, ray_normal_local, obmat, timat, loc, no, dist, depth); - retval |= result; - - if (f->v4 && result == 0) { - retval |= snapFace(ar, verts[f->v3].co, verts[f->v4].co, verts[f->v1].co, verts[f->v2].co, mval, ray_start, ray_start_local, ray_normal_local, obmat, timat, loc, no, dist, depth); - } - } - } - - if (em != NULL) { - EDBM_index_arrays_free(em); - } -#endif - break; } case SCE_SNAP_MODE_VERTEX: { diff --git a/source/blender/editors/util/crazyspace.c b/source/blender/editors/util/crazyspace.c index b0edc702e48..e953aa2f0ed 100644 --- a/source/blender/editors/util/crazyspace.c +++ b/source/blender/editors/util/crazyspace.c @@ -409,7 +409,7 @@ void crazyspace_build_sculpt(Scene *scene, Object *ob, float (**deformmats)[3][3 MEM_freeN(quats); } - if (!*deformmats) { + if (*deformmats == NULL) { int a, numVerts; Mesh *me = (Mesh *)ob->data; diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index 4b008d9a30f..e860d486ea3 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -215,6 +215,8 @@ void ED_uvedit_assign_image(Main *bmain, Scene *scene, Object *obedit, Image *im if (!CustomData_has_layer(&em->bm->pdata, CD_MTEXPOLY)) { BM_data_layer_add(em->bm, &em->bm->pdata, CD_MTEXPOLY); BM_data_layer_add(em->bm, &em->bm->ldata, CD_MLOOPUV); + /* make UVs all nice 0-1 */ + ED_mesh_uv_loop_reset_ex(obedit->data, CustomData_get_active_layer_index(&em->bm->pdata, CD_MTEXPOLY)); update = 1; } diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c index 74d007e92c0..393c119b347 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c @@ -369,7 +369,7 @@ static ParamHandle *construct_param_handle_subsurfed(Scene *scene, BMEditMesh *e /* Used to hold subsurfed Mesh */ DerivedMesh *derivedMesh, *initialDerived; /* holds original indices for subsurfed mesh */ - int *origVertIndices, *origFaceIndices, *origEdgeIndices; + int *origVertIndices, *origEdgeIndices, *origFaceIndices, *origPolyIndices; /* Holds vertices of subsurfed mesh */ MVert *subsurfedVerts; MEdge *subsurfedEdges; @@ -422,6 +422,7 @@ static ParamHandle *construct_param_handle_subsurfed(Scene *scene, BMEditMesh *e origVertIndices = derivedMesh->getVertDataArray(derivedMesh, CD_ORIGINDEX); origEdgeIndices = derivedMesh->getEdgeDataArray(derivedMesh, CD_ORIGINDEX); origFaceIndices = derivedMesh->getTessFaceDataArray(derivedMesh, CD_ORIGINDEX); + origPolyIndices = derivedMesh->getPolyDataArray(derivedMesh, CD_ORIGINDEX); numOfEdges = derivedMesh->getNumEdges(derivedMesh); numOfFaces = derivedMesh->getNumTessFaces(derivedMesh); @@ -433,7 +434,7 @@ static ParamHandle *construct_param_handle_subsurfed(Scene *scene, BMEditMesh *e /* map subsurfed faces to original editFaces */ for (i = 0; i < numOfFaces; i++) - faceMap[i] = EDBM_face_at_index(em, origFaceIndices[i]); + faceMap[i] = EDBM_face_at_index(em, DM_origindex_mface_mpoly(origFaceIndices, origPolyIndices, i)); edgeMap = MEM_mallocN(numOfEdges * sizeof(BMEdge *), "unwrap_edit_edge_map"); @@ -1170,7 +1171,7 @@ static int unwrap_exec(bContext *C, wmOperator *op) int correct_aspect = RNA_boolean_get(op->ptr, "correct_aspect"); int use_subsurf = RNA_boolean_get(op->ptr, "use_subsurf_data"); int subsurf_level = RNA_int_get(op->ptr, "uv_subsurf_level"); - float obsize[3], unitsize[3] = {1.0f, 1.0f, 1.0f}; + float obsize[3]; short implicit = 0; if (!uvedit_have_selection(scene, em, implicit)) { @@ -1183,9 +1184,9 @@ static int unwrap_exec(bContext *C, wmOperator *op) } mat4_to_size(obsize, obedit->obmat); - if (!compare_v3v3(obsize, unitsize, 1e-4f)) + if (!(fabsf(obsize[0] - obsize[1]) < 1e-4f && fabsf(obsize[1] - obsize[2]) < 1e-4f)) BKE_report(op->reports, RPT_INFO, - "Object scale is not 1.0, unwrap will operate on a non-scaled version of the mesh"); + "Object has non-uniform scale, unwrap will operate on a non-scaled version of the mesh"); /* remember last method for live unwrap */ if (RNA_struct_property_is_set(op->ptr, "method")) diff --git a/source/blender/gpu/GPU_buffers.h b/source/blender/gpu/GPU_buffers.h index de83a717bce..36fbd818f11 100644 --- a/source/blender/gpu/GPU_buffers.h +++ b/source/blender/gpu/GPU_buffers.h @@ -123,37 +123,36 @@ void GPU_global_buffer_pool_free(void); GPUBuffer *GPU_buffer_alloc(int size); void GPU_buffer_free(GPUBuffer *buffer); -GPUDrawObject *GPU_drawobject_new(struct DerivedMesh *dm ); -void GPU_drawobject_free(struct DerivedMesh *dm ); +GPUDrawObject *GPU_drawobject_new(struct DerivedMesh *dm); +void GPU_drawobject_free(struct DerivedMesh *dm); /* called before drawing */ -void GPU_vertex_setup(struct DerivedMesh *dm ); -void GPU_normal_setup(struct DerivedMesh *dm ); -void GPU_uv_setup(struct DerivedMesh *dm ); -void GPU_color_setup(struct DerivedMesh *dm ); -void GPU_edge_setup(struct DerivedMesh *dm ); /* does not mix with other data */ -void GPU_uvedge_setup(struct DerivedMesh *dm ); -int GPU_attrib_element_size( GPUAttrib data[], int numdata ); -void GPU_interleaved_attrib_setup( GPUBuffer *buffer, GPUAttrib data[], int numdata ); +void GPU_vertex_setup(struct DerivedMesh *dm); +void GPU_normal_setup(struct DerivedMesh *dm); +void GPU_uv_setup(struct DerivedMesh *dm); +/* colType is the cddata MCol type to use! */ +void GPU_color_setup(struct DerivedMesh *dm, int colType); +void GPU_edge_setup(struct DerivedMesh *dm); /* does not mix with other data */ +void GPU_uvedge_setup(struct DerivedMesh *dm); +int GPU_attrib_element_size(GPUAttrib data[], int numdata); +void GPU_interleaved_attrib_setup(GPUBuffer *buffer, GPUAttrib data[], int numdata); /* can't lock more than one buffer at once */ -void *GPU_buffer_lock( GPUBuffer *buffer ); -void *GPU_buffer_lock_stream( GPUBuffer *buffer ); -void GPU_buffer_unlock( GPUBuffer *buffer ); +void *GPU_buffer_lock(GPUBuffer *buffer); +void *GPU_buffer_lock_stream(GPUBuffer *buffer); +void GPU_buffer_unlock(GPUBuffer *buffer); -/* upload three unsigned chars, representing RGB colors, for each vertex. Resets dm->drawObject->colType to -1 */ -void GPU_color3_upload(struct DerivedMesh *dm, unsigned char *data ); /* switch color rendering on=1/off=0 */ -void GPU_color_switch( int mode ); +void GPU_color_switch(int mode); /* used for drawing edges */ -void GPU_buffer_draw_elements( GPUBuffer *elements, unsigned int mode, int start, int count ); +void GPU_buffer_draw_elements(GPUBuffer *elements, unsigned int mode, int start, int count); /* called after drawing */ void GPU_buffer_unbind(void); /* used to check whether to use the old (without buffers) code */ -int GPU_buffer_legacy(struct DerivedMesh *dm ); +int GPU_buffer_legacy(struct DerivedMesh *dm); /* Buffers for non-DerivedMesh drawing */ typedef struct GPU_Buffers GPU_Buffers; diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c index 3f04de91900..6e475ace09d 100644 --- a/source/blender/gpu/intern/gpu_buffers.c +++ b/source/blender/gpu/intern/gpu_buffers.c @@ -708,34 +708,6 @@ static void GPU_buffer_copy_uv(DerivedMesh *dm, float *varray, int *index, int * } } - -static void GPU_buffer_copy_color3(DerivedMesh *dm, float *varray_, int *index, int *mat_orig_to_new, void *user) -{ - int i, totface; - char *varray = (char *)varray_; - char *mcol = (char *)user; - MFace *f = dm->getTessFaceArray(dm); - - totface = dm->getNumTessFaces(dm); - for (i = 0; i < totface; i++, f++) { - int start = index[mat_orig_to_new[f->mat_nr]]; - - /* v1 v2 v3 */ - copy_v3_v3_char(&varray[start], &mcol[i * 12]); - copy_v3_v3_char(&varray[start + 3], &mcol[i * 12 + 3]); - copy_v3_v3_char(&varray[start + 6], &mcol[i * 12 + 6]); - index[mat_orig_to_new[f->mat_nr]] += 9; - - if (f->v4) { - /* v3 v4 v1 */ - copy_v3_v3_char(&varray[start + 9], &mcol[i * 12 + 6]); - copy_v3_v3_char(&varray[start + 12], &mcol[i * 12 + 9]); - copy_v3_v3_char(&varray[start + 15], &mcol[i * 12]); - index[mat_orig_to_new[f->mat_nr]] += 9; - } - } -} - static void copy_mcol_uc3(unsigned char *v, unsigned char *col) { v[0] = col[3]; @@ -820,28 +792,6 @@ static void GPU_buffer_copy_uvedge(DerivedMesh *dm, float *varray, int *UNUSED(i } } -/* get the DerivedMesh's MCols; choose (in decreasing order of - * preference) from CD_ID_MCOL, CD_PREVIEW_MCOL, or CD_MCOL */ -static MCol *gpu_buffer_color_type(DerivedMesh *dm) -{ - MCol *c; - int type; - - type = CD_ID_MCOL; - c = DM_get_tessface_data_layer(dm, type); - if (!c) { - type = CD_PREVIEW_MCOL; - c = DM_get_tessface_data_layer(dm, type); - if (!c) { - type = CD_MCOL; - c = DM_get_tessface_data_layer(dm, type); - } - } - - dm->drawObject->colType = type; - return c; -} - typedef enum { GPU_BUFFER_VERTEX = 0, GPU_BUFFER_NORMAL, @@ -924,7 +874,7 @@ static GPUBuffer *gpu_buffer_setup_type(DerivedMesh *dm, GPUBufferType type) /* special handling for MCol and UV buffers */ if (type == GPU_BUFFER_COLOR) { - if (!(user_data = gpu_buffer_color_type(dm))) + if (!(user_data = DM_get_tessface_data_layer(dm, dm->drawObject->colType))) return NULL; } else if (type == GPU_BUFFER_UV) { @@ -944,7 +894,7 @@ static GPUBuffer *gpu_buffer_setup_type(DerivedMesh *dm, GPUBufferType type) static GPUBuffer *gpu_buffer_setup_common(DerivedMesh *dm, GPUBufferType type) { GPUBuffer **buf; - + if (!dm->drawObject) dm->drawObject = GPU_drawobject_new(dm); @@ -1006,8 +956,28 @@ void GPU_uv_setup(DerivedMesh *dm) GLStates |= GPU_BUFFER_TEXCOORD_STATE; } -void GPU_color_setup(DerivedMesh *dm) +void GPU_color_setup(DerivedMesh *dm, int colType) { + if (!dm->drawObject) { + /* XXX Not really nice, but we need a valid gpu draw object to set the colType... + * Else we would have to add a new param to gpu_buffer_setup_common. */ + dm->drawObject = GPU_drawobject_new(dm); + dm->dirty &= ~DM_DIRTY_MCOL_UPDATE_DRAW; + dm->drawObject->colType = colType; + } + /* In paint mode, dm may stay the same during stroke, however we still want to update colors! + * Also check in case we changed color type (i.e. which MCol cdlayer we use). */ + else if ((dm->dirty & DM_DIRTY_MCOL_UPDATE_DRAW) || (colType != dm->drawObject->colType)) { + GPUBuffer **buf = gpu_drawobject_buffer_from_type(dm->drawObject, GPU_BUFFER_COLOR); + /* XXX Freeing this buffer is a bit stupid, as geometry has not changed, size should remain the same. + * Not sure though it would be worth defining a sort of gpu_buffer_update func - nor whether + * it is even possible ! */ + GPU_buffer_free(*buf); + *buf = NULL; + dm->dirty &= ~DM_DIRTY_MCOL_UPDATE_DRAW; + dm->drawObject->colType = colType; + } + if (!gpu_buffer_setup_common(dm, GPU_BUFFER_COLOR)) return; @@ -1168,20 +1138,6 @@ void GPU_buffer_unbind(void) glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); } -/* confusion: code in cdderivedmesh calls both GPU_color_setup and - * GPU_color3_upload; both of these set the `colors' buffer, so seems - * like it will just needlessly overwrite? --nicholas */ -void GPU_color3_upload(DerivedMesh *dm, unsigned char *data) -{ - if (dm->drawObject == 0) - dm->drawObject = GPU_drawobject_new(dm); - GPU_buffer_free(dm->drawObject->colors); - - dm->drawObject->colors = gpu_buffer_setup(dm, dm->drawObject, 3, - sizeof(char) * 3 * dm->drawObject->tot_triangle_point, - GL_ARRAY_BUFFER_ARB, data, GPU_buffer_copy_color3); -} - void GPU_color_switch(int mode) { if (mode) { @@ -1271,11 +1227,11 @@ void GPU_buffer_draw_elements(GPUBuffer *elements, unsigned int mode, int start, * drawing and doesn't interact at all with the buffer code above */ /* Return false if VBO is either unavailable or disabled by the user, - true otherwise */ + * true otherwise */ static int gpu_vbo_enabled(void) { return (GLEW_ARB_vertex_buffer_object && - !(U.gameflags & USER_DISABLE_VBO)); + !(U.gameflags & USER_DISABLE_VBO)); } /* Convenience struct for building the VBO. */ @@ -1486,7 +1442,7 @@ void GPU_update_mesh_buffers(GPU_Buffers *buffers, MVert *mvert, fmask = (vmask[fv[0]] + vmask[fv[1]] + vmask[fv[2]] + - vmask[fv[3]]) * 0.25; + vmask[fv[3]]) * 0.25f; } } else { @@ -1959,7 +1915,7 @@ static void gpu_draw_buffers_legacy_mesh(GPU_Buffers *buffers) buffers->vmask[fv[1]] + buffers->vmask[fv[2]]); if (f->v4) - fmask = (fmask + buffers->vmask[fv[3]]) * 0.25; + fmask = (fmask + buffers->vmask[fv[3]]) * 0.25f; else fmask /= 3.0f; gpu_color_from_mask_set(fmask, diffuse_color); diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c index b90e67ac838..b4490e656f3 100644 --- a/source/blender/gpu/intern/gpu_codegen.c +++ b/source/blender/gpu/intern/gpu_codegen.c @@ -1046,17 +1046,20 @@ static void gpu_nodes_get_vertex_attributes(ListBase *nodes, GPUVertexAttribs *a } } - if (a == attribs->totlayer && a < GPU_MAX_ATTRIB) { - input->attribid = attribs->totlayer++; - input->attribfirst = 1; - - attribs->layer[a].type = input->attribtype; - attribs->layer[a].attribid = input->attribid; - BLI_strncpy(attribs->layer[a].name, input->attribname, - sizeof(attribs->layer[a].name)); + if (a < GPU_MAX_ATTRIB) { + if (a == attribs->totlayer) { + input->attribid = attribs->totlayer++; + input->attribfirst = 1; + + attribs->layer[a].type = input->attribtype; + attribs->layer[a].attribid = input->attribid; + BLI_strncpy(attribs->layer[a].name, input->attribname, + sizeof(attribs->layer[a].name)); + } + else { + input->attribid = attribs->layer[a].attribid; + } } - else - input->attribid = attribs->layer[a].attribid; } } } diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c index b40e19e1c9e..7bd72430969 100644 --- a/source/blender/gpu/intern/gpu_draw.c +++ b/source/blender/gpu/intern/gpu_draw.c @@ -620,7 +620,7 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, int compare, int GPU_create_gl_tex(bind, rect, frect, rectw, recth, mipmap, use_high_bit_depth, ima); /* mark as non-color data texture */ - if(*bind) { + if (*bind) { if (is_data) ima->tpageflag |= IMA_GLBIND_IS_DATA; else @@ -739,7 +739,7 @@ int GPU_upload_dxt_texture(ImBuf *ibuf) return FALSE; } - if(!is_power_of_2_i(width) || !is_power_of_2_i(height)) { + if (!is_power_of_2_i(width) || !is_power_of_2_i(height)) { printf("Unable to load non-power-of-two DXT image resolution, falling back to uncompressed\n"); return FALSE; } diff --git a/source/blender/gpu/intern/gpu_extensions.c b/source/blender/gpu/intern/gpu_extensions.c index 21d5482e9cc..cef664437b7 100644 --- a/source/blender/gpu/intern/gpu_extensions.c +++ b/source/blender/gpu/intern/gpu_extensions.c @@ -1295,7 +1295,7 @@ GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader) return retval; } -void GPU_shader_free_builtin_shaders() +void GPU_shader_free_builtin_shaders(void) { if (GG.shaders.vsm_store) { MEM_freeN(GG.shaders.vsm_store); diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index 1fd215b1ec2..ef73764753c 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -1589,8 +1589,8 @@ void GPU_lamp_update_distance(GPULamp *lamp, float distance, float att1, float a void GPU_lamp_update_spot(GPULamp *lamp, float spotsize, float spotblend) { - lamp->spotsi= cos(M_PI*spotsize/360.0); - lamp->spotbl= (1.0f - lamp->spotsi)*spotblend; + lamp->spotsi= cosf((float)M_PI * spotsize / 360.0f); + lamp->spotbl= (1.0f - lamp->spotsi) * spotblend; } static void gpu_lamp_from_blender(Scene *scene, Object *ob, Object *par, Lamp *la, GPULamp *lamp) diff --git a/source/blender/imbuf/CMakeLists.txt b/source/blender/imbuf/CMakeLists.txt index 511b3c64cb5..29ed8c95fc6 100644 --- a/source/blender/imbuf/CMakeLists.txt +++ b/source/blender/imbuf/CMakeLists.txt @@ -81,21 +81,6 @@ set(SRC intern/IMB_indexer.h intern/IMB_metadata.h intern/imbuf.h - intern/cineon/cineonlib.h - intern/cineon/dpxlib.h - intern/cineon/logImageCore.h - intern/cineon/logmemfile.h - intern/dds/BlockDXT.h - intern/dds/Color.h - intern/dds/ColorBlock.h - intern/dds/Common.h - intern/dds/DirectDrawSurface.h - intern/dds/Image.h - intern/dds/PixelFormat.h - intern/dds/Stream.h - intern/dds/dds_api.h - intern/openexr/openexr_api.h - intern/openexr/openexr_multi.h # orphan include ../../../intern/ffmpeg/ffmpeg_compat.h diff --git a/source/blender/imbuf/intern/cineon/CMakeLists.txt b/source/blender/imbuf/intern/cineon/CMakeLists.txt index 8e76f5e729b..b94cfd22058 100644 --- a/source/blender/imbuf/intern/cineon/CMakeLists.txt +++ b/source/blender/imbuf/intern/cineon/CMakeLists.txt @@ -39,6 +39,15 @@ set(INC_SYS ) set(SRC + cin_debug_stuff.h + cineonfile.h + cineonlib.h + dpxfile.h + dpxlib.h + logImageCore.h + logImageLib.h + logmemfile.h + cineon_dpx.c cineonlib.c dpxlib.c diff --git a/source/blender/imbuf/intern/cineon/logImageLib.c b/source/blender/imbuf/intern/cineon/logImageLib.c deleted file mode 100644 index e69de29bb2d..00000000000 --- a/source/blender/imbuf/intern/cineon/logImageLib.c +++ /dev/null diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c index ff474d85a8c..6581987aed7 100644 --- a/source/blender/imbuf/intern/colormanagement.c +++ b/source/blender/imbuf/intern/colormanagement.c @@ -1225,7 +1225,7 @@ static void *display_buffer_apply_get_linear_buffer(DisplayBufferThread *handle) /* first convert byte buffer to float, keep in image space */ for (i = 0, fp = linear_buffer, cp = byte_buffer; i < channels * width * height; - i++, fp++, cp++) + i++, fp++, cp++) { *fp = (float)(*cp) / 255.0f; } diff --git a/source/blender/imbuf/intern/dds/CMakeLists.txt b/source/blender/imbuf/intern/dds/CMakeLists.txt index e0b5a6c10d6..57603725ce1 100644 --- a/source/blender/imbuf/intern/dds/CMakeLists.txt +++ b/source/blender/imbuf/intern/dds/CMakeLists.txt @@ -39,10 +39,21 @@ set(INC_SYS ) set(SRC + BlockDXT.h + Color.h + ColorBlock.h + Common.h + DirectDrawSurface.h + FlipDXT.h + Image.h + PixelFormat.h + Stream.h + dds_api.h + BlockDXT.cpp - FlipDXT.cpp ColorBlock.cpp DirectDrawSurface.cpp + FlipDXT.cpp Image.cpp Stream.cpp dds_api.cpp @@ -52,4 +63,4 @@ if(WITH_IMAGE_DDS) add_definitions(-DWITH_DDS) endif() -blender_add_lib(bf_imbuf_dds "${SRC}" "${INC}" "${INC_SYS}") +blender_add_lib(bf_imbuf_dds "${SRC}" "${INC}" "${INC_SYS}") diff --git a/source/blender/imbuf/intern/dds/Common.h b/source/blender/imbuf/intern/dds/Common.h index 4e3e3e024f7..ab929b82264 100644 --- a/source/blender/imbuf/intern/dds/Common.h +++ b/source/blender/imbuf/intern/dds/Common.h @@ -42,9 +42,9 @@ template<typename T> inline void swap(T & a, T & b) { - T tmp = a; - a = b; - b = tmp; + T tmp = a; + a = b; + b = tmp; } typedef unsigned char uint8; diff --git a/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp b/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp index 1fd41aa8c2d..ccf72f9af86 100644 --- a/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp +++ b/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp @@ -280,19 +280,19 @@ static const uint DDPF_SRGB = 0x40000000U; DXGI_FORMAT_B8G8R8A8_UNORM = 87, DXGI_FORMAT_B8G8R8X8_UNORM = 88, - DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM = 89, - DXGI_FORMAT_B8G8R8A8_TYPELESS = 90, - DXGI_FORMAT_B8G8R8A8_UNORM_SRGB = 91, - DXGI_FORMAT_B8G8R8X8_TYPELESS = 92, - DXGI_FORMAT_B8G8R8X8_UNORM_SRGB = 93, - - DXGI_FORMAT_BC6H_TYPELESS = 94, - DXGI_FORMAT_BC6H_UF16 = 95, - DXGI_FORMAT_BC6H_SF16 = 96, - - DXGI_FORMAT_BC7_TYPELESS = 97, - DXGI_FORMAT_BC7_UNORM = 98, - DXGI_FORMAT_BC7_UNORM_SRGB = 99, + DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM = 89, + DXGI_FORMAT_B8G8R8A8_TYPELESS = 90, + DXGI_FORMAT_B8G8R8A8_UNORM_SRGB = 91, + DXGI_FORMAT_B8G8R8X8_TYPELESS = 92, + DXGI_FORMAT_B8G8R8X8_UNORM_SRGB = 93, + + DXGI_FORMAT_BC6H_TYPELESS = 94, + DXGI_FORMAT_BC6H_UF16 = 95, + DXGI_FORMAT_BC6H_SF16 = 96, + + DXGI_FORMAT_BC7_TYPELESS = 97, + DXGI_FORMAT_BC7_UNORM = 98, + DXGI_FORMAT_BC7_UNORM_SRGB = 99, }; enum D3D10_RESOURCE_DIMENSION @@ -496,60 +496,60 @@ void mem_read(Stream & mem, DDSHeader & header) namespace { - struct FormatDescriptor - { - uint format; - uint bitcount; - uint rmask; - uint gmask; - uint bmask; - uint amask; - }; - - static const FormatDescriptor s_d3dFormats[] = - { - { D3DFMT_R8G8B8, 24, 0xFF0000, 0xFF00, 0xFF, 0 }, - { D3DFMT_A8R8G8B8, 32, 0xFF0000, 0xFF00, 0xFF, 0xFF000000 }, // DXGI_FORMAT_B8G8R8A8_UNORM - { D3DFMT_X8R8G8B8, 32, 0xFF0000, 0xFF00, 0xFF, 0 }, // DXGI_FORMAT_B8G8R8X8_UNORM - { D3DFMT_R5G6B5, 16, 0xF800, 0x7E0, 0x1F, 0 }, // DXGI_FORMAT_B5G6R5_UNORM - { D3DFMT_X1R5G5B5, 16, 0x7C00, 0x3E0, 0x1F, 0 }, - { D3DFMT_A1R5G5B5, 16, 0x7C00, 0x3E0, 0x1F, 0x8000 }, // DXGI_FORMAT_B5G5R5A1_UNORM - { D3DFMT_A4R4G4B4, 16, 0xF00, 0xF0, 0xF, 0xF000 }, - { D3DFMT_R3G3B2, 8, 0xE0, 0x1C, 0x3, 0 }, - { D3DFMT_A8, 8, 0, 0, 0, 8 }, // DXGI_FORMAT_A8_UNORM - { D3DFMT_A8R3G3B2, 16, 0xE0, 0x1C, 0x3, 0xFF00 }, - { D3DFMT_X4R4G4B4, 16, 0xF00, 0xF0, 0xF, 0 }, - { D3DFMT_A2B10G10R10, 32, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000 }, // DXGI_FORMAT_R10G10B10A2 - { D3DFMT_A8B8G8R8, 32, 0xFF, 0xFF00, 0xFF0000, 0xFF000000 }, // DXGI_FORMAT_R8G8B8A8_UNORM - { D3DFMT_X8B8G8R8, 32, 0xFF, 0xFF00, 0xFF0000, 0 }, - { D3DFMT_G16R16, 32, 0xFFFF, 0xFFFF0000, 0, 0 }, // DXGI_FORMAT_R16G16_UNORM - { D3DFMT_A2R10G10B10, 32, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000 }, - { D3DFMT_A2B10G10R10, 32, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000 }, - - { D3DFMT_L8, 8, 8, 0, 0, 0 }, // DXGI_FORMAT_R8_UNORM - { D3DFMT_L16, 16, 16, 0, 0, 0 }, // DXGI_FORMAT_R16_UNORM - }; - - static const uint s_d3dFormatCount = sizeof(s_d3dFormats) / sizeof(s_d3dFormats[0]); +struct FormatDescriptor +{ + uint format; + uint bitcount; + uint rmask; + uint gmask; + uint bmask; + uint amask; +}; + +static const FormatDescriptor s_d3dFormats[] = +{ + { D3DFMT_R8G8B8, 24, 0xFF0000, 0xFF00, 0xFF, 0 }, + { D3DFMT_A8R8G8B8, 32, 0xFF0000, 0xFF00, 0xFF, 0xFF000000 }, /* DXGI_FORMAT_B8G8R8A8_UNORM */ + { D3DFMT_X8R8G8B8, 32, 0xFF0000, 0xFF00, 0xFF, 0 }, /* DXGI_FORMAT_B8G8R8X8_UNORM */ + { D3DFMT_R5G6B5, 16, 0xF800, 0x7E0, 0x1F, 0 }, /* DXGI_FORMAT_B5G6R5_UNORM */ + { D3DFMT_X1R5G5B5, 16, 0x7C00, 0x3E0, 0x1F, 0 }, + { D3DFMT_A1R5G5B5, 16, 0x7C00, 0x3E0, 0x1F, 0x8000 }, /* DXGI_FORMAT_B5G5R5A1_UNORM */ + { D3DFMT_A4R4G4B4, 16, 0xF00, 0xF0, 0xF, 0xF000 }, + { D3DFMT_R3G3B2, 8, 0xE0, 0x1C, 0x3, 0 }, + { D3DFMT_A8, 8, 0, 0, 0, 8 }, /* DXGI_FORMAT_A8_UNORM */ + { D3DFMT_A8R3G3B2, 16, 0xE0, 0x1C, 0x3, 0xFF00 }, + { D3DFMT_X4R4G4B4, 16, 0xF00, 0xF0, 0xF, 0 }, + { D3DFMT_A2B10G10R10, 32, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000 }, /* DXGI_FORMAT_R10G10B10A2 */ + { D3DFMT_A8B8G8R8, 32, 0xFF, 0xFF00, 0xFF0000, 0xFF000000 }, /* DXGI_FORMAT_R8G8B8A8_UNORM */ + { D3DFMT_X8B8G8R8, 32, 0xFF, 0xFF00, 0xFF0000, 0 }, + { D3DFMT_G16R16, 32, 0xFFFF, 0xFFFF0000, 0, 0 }, /* DXGI_FORMAT_R16G16_UNORM */ + { D3DFMT_A2R10G10B10, 32, 0x3FF00000, 0xFFC00, 0x3FF, 0xC0000000 }, + { D3DFMT_A2B10G10R10, 32, 0x3FF, 0xFFC00, 0x3FF00000, 0xC0000000 }, + + { D3DFMT_L8, 8, 8, 0, 0, 0 }, /* DXGI_FORMAT_R8_UNORM */ + { D3DFMT_L16, 16, 16, 0, 0, 0 }, /* DXGI_FORMAT_R16_UNORM */ +}; + +static const uint s_d3dFormatCount = sizeof(s_d3dFormats) / sizeof(s_d3dFormats[0]); } // namespace static uint findD3D9Format(uint bitcount, uint rmask, uint gmask, uint bmask, uint amask) { - for (int i = 0; i < s_d3dFormatCount; i++) - { - if (s_d3dFormats[i].bitcount == bitcount && - s_d3dFormats[i].rmask == rmask && - s_d3dFormats[i].gmask == gmask && - s_d3dFormats[i].bmask == bmask && - s_d3dFormats[i].amask == amask) - { - return s_d3dFormats[i].format; - } - } + for (int i = 0; i < s_d3dFormatCount; i++) + { + if (s_d3dFormats[i].bitcount == bitcount && + s_d3dFormats[i].rmask == rmask && + s_d3dFormats[i].gmask == gmask && + s_d3dFormats[i].bmask == bmask && + s_d3dFormats[i].amask == amask) + { + return s_d3dFormats[i].format; + } + } - return 0; - } + return 0; +} @@ -566,7 +566,7 @@ DDSHeader::DDSHeader() for (uint i = 0; i < 11; i++) this->reserved[i] = 0; // Store version information on the reserved header attributes. - this->reserved[9] = FOURCC_NVTT; + this->reserved[9] = FOURCC_NVTT; this->reserved[10] = (2 << 16) | (1 << 8) | (0); // major.minor.revision this->pf.size = 32; @@ -613,7 +613,7 @@ void DDSHeader::setMipmapCount(uint count) if (count == 0 || count == 1) { this->flags &= ~DDSD_MIPMAPCOUNT; - this->mipmapcount = 1; + this->mipmapcount = 1; if (this->caps.caps2 == 0) { this->caps.caps1 = DDSCAPS_TEXTURE; @@ -715,14 +715,14 @@ void DDSHeader::setPixelFormat(uint bitcount, uint rmask, uint gmask, uint bmask if (rmask != 0 || gmask != 0 || bmask != 0) { - if (gmask == 0 && bmask == 0) - { - this->pf.flags = DDPF_LUMINANCE; - } - else - { - this->pf.flags = DDPF_RGB; - } + if (gmask == 0 && bmask == 0) + { + this->pf.flags = DDPF_LUMINANCE; + } + else + { + this->pf.flags = DDPF_RGB; + } if (amask != 0) { this->pf.flags |= DDPF_ALPHAPIXELS; @@ -743,11 +743,11 @@ void DDSHeader::setPixelFormat(uint bitcount, uint rmask, uint gmask, uint bmask } } - // D3DX functions do not like this: + // D3DX functions do not like this: this->pf.fourcc = 0; //findD3D9Format(bitcount, rmask, gmask, bmask, amask); - /*if (this->pf.fourcc) { - this->pf.flags |= DDPF_FOURCC; - }*/ + /*if (this->pf.fourcc) { + this->pf.flags |= DDPF_FOURCC; + }*/ if (!(bitcount > 0 && bitcount <= 32)) { printf("DDS: bad bit count, pixel format not set\n"); @@ -775,8 +775,8 @@ void DDSHeader::setNormalFlag(bool b) void DDSHeader::setSrgbFlag(bool b) { - if (b) this->pf.flags |= DDPF_SRGB; - else this->pf.flags &= ~DDPF_SRGB; + if (b) this->pf.flags |= DDPF_SRGB; + else this->pf.flags &= ~DDPF_SRGB; } void DDSHeader::setHasAlphaFlag(bool b) @@ -787,8 +787,8 @@ void DDSHeader::setHasAlphaFlag(bool b) void DDSHeader::setUserVersion(int version) { - this->reserved[7] = FOURCC_UVER; - this->reserved[8] = version; + this->reserved[7] = FOURCC_UVER; + this->reserved[8] = version; } /* @@ -836,45 +836,45 @@ bool DDSHeader::hasDX10Header() const uint DDSHeader::signature() const { - return this->reserved[9]; + return this->reserved[9]; } uint DDSHeader::toolVersion() const { - return this->reserved[10]; + return this->reserved[10]; } uint DDSHeader::userVersion() const { - if (this->reserved[7] == FOURCC_UVER) { - return this->reserved[8]; - } - return 0; + if (this->reserved[7] == FOURCC_UVER) { + return this->reserved[8]; + } + return 0; } bool DDSHeader::isNormalMap() const { - return (pf.flags & DDPF_NORMAL) != 0; + return (pf.flags & DDPF_NORMAL) != 0; } bool DDSHeader::isSrgb() const { - return (pf.flags & DDPF_SRGB) != 0; + return (pf.flags & DDPF_SRGB) != 0; } bool DDSHeader::hasAlpha() const { - return (pf.flags & DDPF_ALPHAPIXELS) != 0; + return (pf.flags & DDPF_ALPHAPIXELS) != 0; } uint DDSHeader::d3d9Format() const { - if (pf.flags & DDPF_FOURCC) { - return pf.fourcc; - } - else { - return findD3D9Format(pf.bitcount, pf.rmask, pf.gmask, pf.bmask, pf.amask); - } + if (pf.flags & DDPF_FOURCC) { + return pf.fourcc; + } + else { + return findD3D9Format(pf.bitcount, pf.rmask, pf.gmask, pf.bmask, pf.amask); + } } DirectDrawSurface::DirectDrawSurface(unsigned char *mem, uint size) : stream(mem, size), header() @@ -949,9 +949,9 @@ bool DirectDrawSurface::isSupported() const return false; } } - else if ((header.pf.flags & DDPF_RGB) || (header.pf.flags & DDPF_LUMINANCE)) - { - // All RGB and luminance formats are supported now. + else if ((header.pf.flags & DDPF_RGB) || (header.pf.flags & DDPF_LUMINANCE)) + { + // All RGB and luminance formats are supported now. } else { @@ -1001,7 +1001,7 @@ bool DirectDrawSurface::hasAlpha() const } else { - // @@ Here we could check the ALPHA_PIXELS flag, but nobody sets it. (except us?) + // @@ Here we could check the ALPHA_PIXELS flag, but nobody sets it. (except us?) return true; } } @@ -1089,7 +1089,7 @@ void DirectDrawSurface::setHasAlphaFlag(bool b) void DirectDrawSurface::setUserVersion(int version) { - header.setUserVersion(version); + header.setUserVersion(version); } void DirectDrawSurface::mipmap(Image * img, uint face, uint mipmap) @@ -1268,15 +1268,15 @@ void DirectDrawSurface::readBlock(ColorBlock * rgba) block.decodeBlock(rgba); } else if (fourcc == FOURCC_DXT2 || - header.pf.fourcc == FOURCC_DXT3) + header.pf.fourcc == FOURCC_DXT3) { BlockDXT3 block; mem_read(stream, block); block.decodeBlock(rgba); } else if (fourcc == FOURCC_DXT4 || - header.pf.fourcc == FOURCC_DXT5 || - header.pf.fourcc == FOURCC_RXGB) + header.pf.fourcc == FOURCC_DXT5 || + header.pf.fourcc == FOURCC_RXGB) { BlockDXT5 block; mem_read(stream, block); @@ -1393,8 +1393,8 @@ uint DirectDrawSurface::mipmapSize(uint mipmap) const } else if (header.pf.flags & DDPF_RGB || (header.pf.flags & DDPF_LUMINANCE)) { - uint pitch = computePitch(w, header.pf.bitcount, 8); // Asuming 8 bit alignment, which is the same D3DX expects. - + uint pitch = computePitch(w, header.pf.bitcount, 8); // Asuming 8 bit alignment, which is the same D3DX expects. + return pitch * h * d; } else { @@ -1461,7 +1461,7 @@ void DirectDrawSurface::printInfo() const printf("Pixel Format:\n"); printf("\tFlags: 0x%.8X\n", header.pf.flags); if (header.pf.flags & DDPF_RGB) printf("\t\tDDPF_RGB\n"); - if (header.pf.flags & DDPF_LUMINANCE) printf("\t\tDDPF_LUMINANCE\n"); + if (header.pf.flags & DDPF_LUMINANCE) printf("\t\tDDPF_LUMINANCE\n"); if (header.pf.flags & DDPF_FOURCC) printf("\t\tDDPF_FOURCC\n"); if (header.pf.flags & DDPF_ALPHAPIXELS) printf("\t\tDDPF_ALPHAPIXELS\n"); if (header.pf.flags & DDPF_ALPHA) printf("\t\tDDPF_ALPHA\n"); @@ -1472,24 +1472,24 @@ void DirectDrawSurface::printInfo() const if (header.pf.flags & DDPF_ALPHAPREMULT) printf("\t\tDDPF_ALPHAPREMULT\n"); if (header.pf.flags & DDPF_NORMAL) printf("\t\tDDPF_NORMAL\n"); - if (header.pf.fourcc != 0) { - // Display fourcc code even when DDPF_FOURCC flag not set. - printf("\tFourCC: '%c%c%c%c' (0x%.8X)\n", - ((header.pf.fourcc >> 0) & 0xFF), - ((header.pf.fourcc >> 8) & 0xFF), - ((header.pf.fourcc >> 16) & 0xFF), - ((header.pf.fourcc >> 24) & 0xFF), - header.pf.fourcc); - } - - if ((header.pf.flags & DDPF_FOURCC) && (header.pf.bitcount != 0)) + if (header.pf.fourcc != 0) { + // Display fourcc code even when DDPF_FOURCC flag not set. + printf("\tFourCC: '%c%c%c%c' (0x%.8X)\n", + ((header.pf.fourcc >> 0) & 0xFF), + ((header.pf.fourcc >> 8) & 0xFF), + ((header.pf.fourcc >> 16) & 0xFF), + ((header.pf.fourcc >> 24) & 0xFF), + header.pf.fourcc); + } + + if ((header.pf.flags & DDPF_FOURCC) && (header.pf.bitcount != 0)) { - printf("\tSwizzle: '%c%c%c%c' (0x%.8X)\n", - (header.pf.bitcount >> 0) & 0xFF, - (header.pf.bitcount >> 8) & 0xFF, - (header.pf.bitcount >> 16) & 0xFF, - (header.pf.bitcount >> 24) & 0xFF, - header.pf.bitcount); + printf("\tSwizzle: '%c%c%c%c' (0x%.8X)\n", + (header.pf.bitcount >> 0) & 0xFF, + (header.pf.bitcount >> 8) & 0xFF, + (header.pf.bitcount >> 16) & 0xFF, + (header.pf.bitcount >> 24) & 0xFF, + header.pf.bitcount); } else { @@ -1535,7 +1535,7 @@ void DirectDrawSurface::printInfo() const printf("\tArray size: %u\n", header.header10.arraySize); } - if (header.reserved[9] == FOURCC_NVTT) + if (header.reserved[9] == FOURCC_NVTT) { int major = (header.reserved[10] >> 16) & 0xFF; int minor = (header.reserved[10] >> 8) & 0xFF; @@ -1545,9 +1545,9 @@ void DirectDrawSurface::printInfo() const printf("\tNVIDIA Texture Tools %d.%d.%d\n", major, minor, revision); } - if (header.reserved[7] == FOURCC_UVER) - { - printf("User Version: %u\n", header.reserved[8]); - } + if (header.reserved[7] == FOURCC_UVER) + { + printf("User Version: %u\n", header.reserved[8]); + } } diff --git a/source/blender/imbuf/intern/dds/DirectDrawSurface.h b/source/blender/imbuf/intern/dds/DirectDrawSurface.h index ccac1c08b41..72a524daba2 100644 --- a/source/blender/imbuf/intern/dds/DirectDrawSurface.h +++ b/source/blender/imbuf/intern/dds/DirectDrawSurface.h @@ -169,7 +169,7 @@ public: void setNormalFlag(bool b); void setHasAlphaFlag(bool b); - void setUserVersion(int version); + void setUserVersion(int version); void mipmap(Image * img, uint f, uint m); void* readData(uint &size); diff --git a/source/blender/imbuf/intern/dds/FlipDXT.cpp b/source/blender/imbuf/intern/dds/FlipDXT.cpp index 1a577c4dafb..ee7a0ebb2f7 100644 --- a/source/blender/imbuf/intern/dds/FlipDXT.cpp +++ b/source/blender/imbuf/intern/dds/FlipDXT.cpp @@ -173,10 +173,10 @@ static void FlipDXT5BlockHalf(uint8_t *block) int FlipDXTCImage(unsigned int width, unsigned int height, unsigned int levels, int fourcc, uint8_t *data) { // must have valid dimensions - if(width == 0 || height == 0) + if (width == 0 || height == 0) return 0; // height must be a power-of-two - if((height & (height - 1)) != 0) + if ((height & (height - 1)) != 0) return 0; FlipBlockFunction full_block_function; diff --git a/source/blender/imbuf/intern/indexer.c b/source/blender/imbuf/intern/indexer.c index 593e08062fe..5dda33dfd62 100644 --- a/source/blender/imbuf/intern/indexer.c +++ b/source/blender/imbuf/intern/indexer.c @@ -870,9 +870,9 @@ static void index_rebuild_ffmpeg_proc_decoded_frame( context->start_pts_set = TRUE; } - context->frameno = floor((pts - context->start_pts) - * context->pts_time_base - * context->frame_rate + 0.5f); + context->frameno = floor((pts - context->start_pts) * + context->pts_time_base * + context->frame_rate + 0.5f); /* decoding starts *always* on I-Frames, * so: P-Frames won't work, even if all the diff --git a/source/blender/imbuf/intern/openexr/CMakeLists.txt b/source/blender/imbuf/intern/openexr/CMakeLists.txt index a5afc1abdc6..d5cb8e8a3b6 100644 --- a/source/blender/imbuf/intern/openexr/CMakeLists.txt +++ b/source/blender/imbuf/intern/openexr/CMakeLists.txt @@ -39,6 +39,9 @@ set(INC_SYS ) set(SRC + openexr_api.h + openexr_multi.h + openexr_api.cpp ) @@ -49,4 +52,4 @@ if(WITH_IMAGE_OPENEXR) add_definitions(-DWITH_OPENEXR) endif() -blender_add_lib(bf_imbuf_openexr "${SRC}" "${INC}" "${INC_SYS}") +blender_add_lib(bf_imbuf_openexr "${SRC}" "${INC}" "${INC_SYS}") diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp index 066d07a36c5..60c6e184070 100644 --- a/source/blender/imbuf/intern/openexr/openexr_api.cpp +++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp @@ -238,19 +238,19 @@ public: Iex::throwErrnoExc(); } - virtual void write(const char c[], int n) + virtual void write(const char c[], int n) { errno = 0; ofs.write(c, n); check_error(); } - virtual Int64 tellp() + virtual Int64 tellp() { return std::streamoff(ofs.tellp()); } - virtual void seekp(Int64 pos) + virtual void seekp(Int64 pos) { ofs.seekp(pos); check_error(); diff --git a/source/blender/makesdna/DNA_customdata_types.h b/source/blender/makesdna/DNA_customdata_types.h index 9d40af92638..6f7bb5a723e 100644 --- a/source/blender/makesdna/DNA_customdata_types.h +++ b/source/blender/makesdna/DNA_customdata_types.h @@ -80,7 +80,7 @@ typedef struct CustomData { #define CD_MCOL 6 #define CD_ORIGINDEX 7 #define CD_NORMAL 8 -#define CD_POLYINDEX 9 +//#define CD_POLYINDEX 9 #define CD_PROP_FLT 10 #define CD_PROP_INT 11 #define CD_PROP_STR 12 @@ -124,7 +124,7 @@ typedef struct CustomData { #define CD_MASK_MCOL (1 << CD_MCOL) #define CD_MASK_ORIGINDEX (1 << CD_ORIGINDEX) #define CD_MASK_NORMAL (1 << CD_NORMAL) -#define CD_MASK_POLYINDEX (1 << CD_POLYINDEX) +// #define CD_MASK_POLYINDEX (1 << CD_POLYINDEX) #define CD_MASK_PROP_FLT (1 << CD_PROP_FLT) #define CD_MASK_PROP_INT (1 << CD_PROP_INT) #define CD_MASK_PROP_STR (1 << CD_PROP_STR) diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index aa382632b7b..bebe2ba20d5 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -703,6 +703,26 @@ typedef struct NodeTrackPosData { char track_name[64]; } NodeTrackPosData; +typedef struct NodeShaderScript { + int mode; + int flag; + + char filepath[1024]; /* 1024 = FILE_MAX */ + + char bytecode_hash[64]; + char *bytecode; + + IDProperty *prop; +} NodeShaderScript; + +/* script node mode */ +#define NODE_SCRIPT_INTERNAL 0 +#define NODE_SCRIPT_EXTERNAL 1 + +/* script node flag */ +#define NODE_SCRIPT_AUTO_UPDATE 1 + + /* frame node flags */ #define NODE_FRAME_SHRINK 1 /* keep the bounding box minimal */ #define NODE_FRAME_RESIZEABLE 2 /* test flag, if frame can be resized by user */ diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index 2fc04c4a5db..29f6499986c 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -209,7 +209,9 @@ typedef struct Object { float step_height; float jump_speed; float fall_speed; - char pad1[4]; + + /** Collision mask settings */ + unsigned short col_group, col_mask; short rotmode; /* rotation mode - uses defines set out in DNA_action_types.h for PoseChannel rotations... */ @@ -479,6 +481,9 @@ typedef struct DupliObject { /* controller state */ #define OB_MAX_STATES 30 +/* collision masks */ +#define OB_MAX_COL_MASKS 8 + /* ob->gameflag */ #define OB_DYNAMIC 1 #define OB_CHILD 2 diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index 8c81a63ed4c..c327319c403 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -492,6 +492,7 @@ extern StructRNA RNA_ShaderNodeMath; extern StructRNA RNA_ShaderNodeMixRGB; extern StructRNA RNA_ShaderNodeNormal; extern StructRNA RNA_ShaderNodeOutput; +extern StructRNA RNA_ShaderNodeScript; extern StructRNA RNA_ShaderNodeRGB; extern StructRNA RNA_ShaderNodeRGBCurve; extern StructRNA RNA_ShaderNodeRGBToBW; @@ -1067,6 +1068,13 @@ short RNA_type_to_ID_code(StructRNA *type); StructRNA *ID_code_to_RNA_type(short idcode); +#define RNA_POINTER_INVALIDATE(ptr) { \ + /* this is checked for validity */ \ + (ptr)->type = \ + /* should not be needed but prevent bad pointer access, just in case */ \ + (ptr)->id.data = NULL; \ +} (void)0 + /* macro which inserts the function name */ #if defined __GNUC__ || defined __sun # define RNA_warning(format, args ...) _RNA_warning("%s: " format "\n", __func__, ##args) diff --git a/source/blender/makesrna/RNA_types.h b/source/blender/makesrna/RNA_types.h index 7d6e07baebd..87504dc6eb7 100644 --- a/source/blender/makesrna/RNA_types.h +++ b/source/blender/makesrna/RNA_types.h @@ -313,6 +313,7 @@ typedef enum FunctionFlag { FUNC_USE_CONTEXT = 4, FUNC_USE_REPORTS = 8, FUNC_USE_SELF_ID = 2048, + FUNC_ALLOW_WRITE = 4096, /* registering */ FUNC_REGISTER = 16, diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c index d7a7452be05..317204b36dc 100644 --- a/source/blender/makesrna/intern/makesrna.c +++ b/source/blender/makesrna/intern/makesrna.c @@ -1661,6 +1661,7 @@ static void rna_def_property_funcs_header_cpp(FILE *f, StructRNA *srna, Property case PROP_STRING: { fprintf(f, "\tinline std::string %s(void);", rna_safe_id(prop->identifier)); + fprintf(f, "\tinline void %s(const std::string& value);", rna_safe_id(prop->identifier)); break; } case PROP_POINTER: @@ -1676,13 +1677,17 @@ static void rna_def_property_funcs_header_cpp(FILE *f, StructRNA *srna, Property case PROP_COLLECTION: { CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)dp->prop; + const char *collection_funcs = "DefaultCollectionFunctions"; + + if (!(dp->prop->flag & (PROP_IDPROPERTY | PROP_BUILTIN)) && cprop->property.srna) + collection_funcs = (char*)cprop->property.srna; if (cprop->item_type) - fprintf(f, "\tCOLLECTION_PROPERTY(%s, %s, %s, %s, %s, %s)", (const char *)cprop->item_type, srna->identifier, + fprintf(f, "\tCOLLECTION_PROPERTY(%s, %s, %s, %s, %s, %s, %s)", collection_funcs, (const char *)cprop->item_type, srna->identifier, rna_safe_id(prop->identifier), (cprop->length ? "TRUE" : "FALSE"), (cprop->lookupint ? "TRUE" : "FALSE"), (cprop->lookupstring ? "TRUE" : "FALSE")); else - fprintf(f, "\tCOLLECTION_PROPERTY(%s, %s, %s, %s, %s, %s)", "UnknownType", srna->identifier, + fprintf(f, "\tCOLLECTION_PROPERTY(%s, %s, %s, %s, %s, %s, %s)", collection_funcs, "UnknownType", srna->identifier, rna_safe_id(prop->identifier), (cprop->length ? "TRUE" : "FALSE"), (cprop->lookupint ? "TRUE" : "FALSE"), (cprop->lookupstring ? "TRUE" : "FALSE")); break; @@ -1730,9 +1735,6 @@ static void rna_def_struct_function_prototype_cpp(FILE *f, StructRNA *srna, Func if (func->flag & FUNC_USE_CONTEXT) WRITE_PARAM("Context C"); - if (func->flag & FUNC_USE_REPORTS) - WRITE_PARAM("void *reports"); - for (dp = dfunc->cont.properties.first; dp; dp = dp->next) { int type, flag, pout; const char *ptrstr; @@ -1746,6 +1748,8 @@ static void rna_def_struct_function_prototype_cpp(FILE *f, StructRNA *srna, Func if (type == PROP_POINTER) ptrstr = ""; + else if ((type == PROP_POINTER) && (flag & PROP_RNAPTR) && !(flag & PROP_THICK_WRAP)) + ptrstr = "*"; else if (type == PROP_POINTER || dp->prop->arraydimension) ptrstr = "*"; else if (type == PROP_STRING && (flag & PROP_THICK_WRAP)) @@ -1905,7 +1909,7 @@ static void rna_def_struct_function_call_impl_cpp(FILE *f, StructRNA *srna, Func WRITE_PARAM("(::bContext *) C.ptr.data"); if (func->flag & FUNC_USE_REPORTS) - WRITE_PARAM("(::ReportList *) reports"); + WRITE_PARAM("NULL"); dp = dfunc->cont.properties.first; for (; dp; dp = dp->next) { @@ -1918,7 +1922,10 @@ static void rna_def_struct_function_call_impl_cpp(FILE *f, StructRNA *srna, Func fprintf(f, "%s_len, ", dp->prop->identifier); if (dp->prop->type == PROP_POINTER) - fprintf(f, "(::%s *) %s.ptr.data", rna_parameter_type_name(dp->prop), rna_safe_id(dp->prop->identifier)); + if ((dp->prop->flag & PROP_RNAPTR) && !(dp->prop->flag & PROP_THICK_WRAP)) + fprintf(f, "(::%s *) &%s.ptr", rna_parameter_type_name(dp->prop), rna_safe_id(dp->prop->identifier)); + else + fprintf(f, "(::%s *) %s.ptr.data", rna_parameter_type_name(dp->prop), rna_safe_id(dp->prop->identifier)); else fprintf(f, "%s", rna_safe_id(dp->prop->identifier)); } @@ -1946,23 +1953,23 @@ static void rna_def_struct_function_impl_cpp(FILE *f, StructRNA *srna, FunctionD if (dp->prop->type == PROP_POINTER) { pprop = (PointerPropertyRNA *) dp->prop; - fprintf(f, "\t\tPointerRNA ptr;\n"); + fprintf(f, "\t\tPointerRNA result;\n"); if ((dp->prop->flag & PROP_RNAPTR) == 0) { StructRNA *ret_srna = rna_find_struct((const char *) pprop->type); fprintf(f, "\t\t::%s *retdata = ", rna_parameter_type_name(dp->prop)); rna_def_struct_function_call_impl_cpp(f, srna, dfunc); if (ret_srna->flag & STRUCT_ID) - fprintf(f, "\t\tRNA_id_pointer_create((::ID *) retdata, &ptr);\n"); + fprintf(f, "\t\tRNA_id_pointer_create((::ID *) retdata, &result);\n"); else - fprintf(f, "\t\tRNA_pointer_create(NULL, &RNA_%s, retdata, &ptr);\n", (const char *) pprop->type); + fprintf(f, "\t\tRNA_pointer_create((::ID *) ptr.id.data, &RNA_%s, retdata, &result);\n", (const char *) pprop->type); } else { - fprintf(f, "\t\tptr = "); + fprintf(f, "\t\tresult = "); rna_def_struct_function_call_impl_cpp(f, srna, dfunc); } - fprintf(f, "\t\treturn %s(ptr);\n", (const char *) pprop->type); + fprintf(f, "\t\treturn %s(result);\n", (const char *) pprop->type); } else { fprintf(f, "\t\treturn "); @@ -2095,6 +2102,8 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA /* fixed size arrays and RNA pointers are pre-allocated on the ParameterList stack, pass a pointer to it */ else if (type == PROP_POINTER || dparm->prop->arraydimension) ptrstr = "*"; + else if ((type == PROP_POINTER) && (flag & PROP_RNAPTR) && !(flag & PROP_THICK_WRAP)) + ptrstr = "*"; /* PROP_THICK_WRAP strings are pre-allocated on the ParameterList stack, * but type name for string props is already char*, so leave empty */ else if (type == PROP_STRING && (flag & PROP_THICK_WRAP)) @@ -2146,6 +2155,10 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA ptrstr = "**"; valstr = "*"; } + else if ((type == PROP_POINTER) && !(flag & PROP_THICK_WRAP)) { + ptrstr = "**"; + valstr = "*"; + } else if (type == PROP_POINTER || dparm->prop->arraydimension) { ptrstr = "*"; valstr = ""; @@ -3349,6 +3362,8 @@ static const char *cpp_classes = "" " int len= sname##_##identifier##_length(&ptr); \\\n" " std::string str; str.resize(len); \\\n" " sname##_##identifier##_get(&ptr, &str[0]); return str; } \\\n" +" inline void sname::identifier(const std::string& value) { \\\n" +" sname##_##identifier##_set(&ptr, value.c_str()); } \\\n" "\n" "#define POINTER_PROPERTY(type, sname, identifier) \\\n" " inline type sname::identifier(void) { return type(sname##_##identifier##_get(&ptr)); }\n" @@ -3374,20 +3389,21 @@ static const char *cpp_classes = "" " inline static int sname##_##identifier##_lookup_int_wrap(PointerRNA *ptr, int key, PointerRNA *r_ptr) \\\n" " { \\\n" " CollectionPropertyIterator iter; \\\n" -" int i = 0; \\\n" +" int i = 0, found = 0; \\\n" " sname##_##identifier##_begin(&iter, ptr); \\\n" " while (iter.valid) { \\\n" " if (i == key) { \\\n" " *r_ptr = iter.ptr; \\\n" +" found = 1; \\\n" " break; \\\n" " } \\\n" " sname##_##identifier##_next(&iter); \\\n" " ++i; \\\n" " } \\\n" " sname##_##identifier##_end(&iter); \\\n" -" if (!iter.valid) \\\n" +" if (!found) \\\n" " memset(r_ptr, 0, sizeof(*r_ptr)); \\\n" -" return iter.valid; \\\n" +" return found; \\\n" " } \n" "#define COLLECTION_PROPERTY_LOOKUP_INT_TRUE(sname, identifier) \\\n" " inline static int sname##_##identifier##_lookup_int_wrap(PointerRNA *ptr, int key, PointerRNA *r_ptr) \\\n" @@ -3403,7 +3419,7 @@ static const char *cpp_classes = "" " inline static int sname##_##identifier##_lookup_string_wrap(PointerRNA *ptr, const char *key, PointerRNA *r_ptr) \\\n" " { return sname##_##identifier##_lookup_string(ptr, key, r_ptr); } \n" "\n" -"#define COLLECTION_PROPERTY(type, sname, identifier, has_length, has_lookup_int, has_lookup_string) \\\n" +"#define COLLECTION_PROPERTY(collection_funcs, type, sname, identifier, has_length, has_lookup_int, has_lookup_string) \\\n" " typedef CollectionIterator<type, sname##_##identifier##_begin, \\\n" " sname##_##identifier##_next, sname##_##identifier##_end> identifier##_iterator; \\\n" " COLLECTION_PROPERTY_LENGTH_##has_length(sname, identifier) \\\n" @@ -3412,7 +3428,7 @@ static const char *cpp_classes = "" " Collection<sname, type, sname##_##identifier##_begin, \\\n" " sname##_##identifier##_next, sname##_##identifier##_end, \\\n" " sname##_##identifier##_length_wrap, \\\n" -" sname##_##identifier##_lookup_int_wrap, sname##_##identifier##_lookup_string_wrap> identifier;\n" +" sname##_##identifier##_lookup_int_wrap, sname##_##identifier##_lookup_string_wrap, collection_funcs> identifier;\n" "\n" "class Pointer {\n" "public:\n" @@ -3500,10 +3516,11 @@ static const char *cpp_classes = "" "};\n" "\n" "template<typename Tp, typename T, TBeginFunc Tbegin, TNextFunc Tnext, TEndFunc Tend,\n" -" TLengthFunc Tlength, TLookupIntFunc Tlookup_int, TLookupStringFunc Tlookup_string>\n" -"class Collection {\n" +" TLengthFunc Tlength, TLookupIntFunc Tlookup_int, TLookupStringFunc Tlookup_string,\n" +" typename Tcollection_funcs>\n" +"class Collection : public Tcollection_funcs {\n" "public:\n" -" Collection(const PointerRNA &p) : ptr(p) {}\n" +" Collection(const PointerRNA &p) : Tcollection_funcs(p), ptr(p) {}\n" "\n" " void begin(CollectionIterator<T, Tbegin, Tnext, Tend>& iter)\n" " { iter.begin(ptr); }\n" @@ -3512,22 +3529,83 @@ static const char *cpp_classes = "" "" " int length()\n" " { return Tlength(&ptr); }\n" -" T& operator[](int key)\n" -" { PointerRNA r_ptr; Tlookup_int(&ptr, key, &r_ptr); return *(T*)r_ptr.data; }\n" -" T& operator[](const std::string &key)\n" -" { PointerRNA r_ptr; Tlookup_string(&ptr, key.c_str(), &r_ptr); return *(T*)r_ptr.data; }\n" +" T operator[](int key)\n" +" { PointerRNA r_ptr; Tlookup_int(&ptr, key, &r_ptr); return T(r_ptr); }\n" +" T operator[](const std::string &key)\n" +" { PointerRNA r_ptr; Tlookup_string(&ptr, key.c_str(), &r_ptr); return T(r_ptr); }\n" "\n" "private:\n" " PointerRNA ptr;\n" "};\n" +"\n" +"class DefaultCollectionFunctions {\n" +"public:\n" +" DefaultCollectionFunctions(const PointerRNA &p) {}\n" +"};\n" +"\n" "\n"; +static int rna_is_collection_prop(PropertyRNA *prop) +{ + if (!(prop->flag & (PROP_IDPROPERTY | PROP_BUILTIN))) + if (prop->type == PROP_COLLECTION) + return 1; + + return 0; +} + +static int rna_is_collection_functions_struct(const char **collection_structs, const char *struct_name) +{ + int a = 0, found = 0; + + while (collection_structs[a]) { + if (!strcmp(collection_structs[a], struct_name)) { + found = 1; + break; + } + a++; + } + + return found; +} + +static void rna_generate_header_class_cpp(StructDefRNA *ds, FILE *f) +{ + StructRNA *srna = ds->srna; + PropertyDefRNA *dp; + FunctionDefRNA *dfunc; + + fprintf(f, "/**************** %s ****************/\n\n", srna->name); + + fprintf(f, "class %s : public %s {\n", srna->identifier, (srna->base) ? srna->base->identifier : "Pointer"); + fprintf(f, "public:\n"); + fprintf(f, "\t%s(const PointerRNA &ptr_arg) :\n\t\t%s(ptr_arg)", srna->identifier, + (srna->base) ? srna->base->identifier : "Pointer"); + for (dp = ds->cont.properties.first; dp; dp = dp->next) + if (rna_is_collection_prop(dp->prop)) + fprintf(f, ",\n\t\t%s(ptr_arg)", dp->prop->identifier); + fprintf(f, "\n\t\t{}\n\n"); + + for (dp = ds->cont.properties.first; dp; dp = dp->next) + rna_def_property_funcs_header_cpp(f, ds->srna, dp); + + fprintf(f, "\n"); + for (dfunc = ds->functions.first; dfunc; dfunc = dfunc->cont.next) + rna_def_struct_function_header_cpp(f, srna, dfunc); + + fprintf(f, "};\n\n"); +} + static void rna_generate_header_cpp(BlenderRNA *UNUSED(brna), FILE *f) { StructDefRNA *ds; PropertyDefRNA *dp; StructRNA *srna; FunctionDefRNA *dfunc; + const char *first_collection_func_struct = NULL; + const char *collection_func_structs[256] = {NULL}; + int all_collection_func_structs = 0; + int max_collection_func_structs = sizeof(collection_func_structs) / sizeof(collection_func_structs[0]) - 1; fprintf(f, "\n#ifndef __RNA_BLENDER_CPP_H__\n"); fprintf(f, "#define __RNA_BLENDER_CPP_H__\n\n"); @@ -3544,33 +3622,59 @@ static void rna_generate_header_cpp(BlenderRNA *UNUSED(brna), FILE *f) fprintf(f, "/**************** Declarations ****************/\n\n"); - for (ds = DefRNA.structs.first; ds; ds = ds->cont.next) + for (ds = DefRNA.structs.first; ds; ds = ds->cont.next) { fprintf(f, "class %s;\n", ds->srna->identifier); + } fprintf(f, "\n"); + /* first get list of all structures used as collection functions, so they'll be declared first */ for (ds = DefRNA.structs.first; ds; ds = ds->cont.next) { - srna = ds->srna; + for (dp = ds->cont.properties.first; dp; dp = dp->next) { + if (rna_is_collection_prop(dp->prop)) { + PropertyRNA *prop = dp->prop; + + if (prop->srna) { + /* store name of structure which first uses custom functions for collections */ + if (first_collection_func_struct == NULL) + first_collection_func_struct = ds->srna->identifier; + + if (!rna_is_collection_functions_struct(collection_func_structs, (char*)prop->srna)) { + if (all_collection_func_structs >= max_collection_func_structs) { + printf("Array size to store all collection structures names is too small\n"); + exit(1); + } - fprintf(f, "/**************** %s ****************/\n\n", srna->name); + collection_func_structs[all_collection_func_structs++] = (char*)prop->srna; + } + } + } + } + } - fprintf(f, "class %s : public %s {\n", srna->identifier, (srna->base) ? srna->base->identifier : "Pointer"); - fprintf(f, "public:\n"); - fprintf(f, "\t%s(const PointerRNA &ptr_arg) :\n\t\t%s(ptr_arg)", srna->identifier, - (srna->base) ? srna->base->identifier : "Pointer"); - for (dp = ds->cont.properties.first; dp; dp = dp->next) - if (!(dp->prop->flag & (PROP_IDPROPERTY | PROP_BUILTIN))) - if (dp->prop->type == PROP_COLLECTION) - fprintf(f, ",\n\t\t%s(ptr_arg)", dp->prop->identifier); - fprintf(f, "\n\t\t{}\n\n"); + /* declare all structures in such order: + * - first N structures which doesn't use custom functions for collections + * - all structures used for custom functions in collections + * - all the rest structures + * such an order prevents usage of non-declared classes + */ + for (ds = DefRNA.structs.first; ds; ds = ds->cont.next) { + srna = ds->srna; - for (dp = ds->cont.properties.first; dp; dp = dp->next) - rna_def_property_funcs_header_cpp(f, ds->srna, dp); + if (!strcmp(srna->identifier, first_collection_func_struct)) { + StructDefRNA *ds2; + StructRNA *srna2; - fprintf(f, "\n"); - for (dfunc = ds->functions.first; dfunc; dfunc = dfunc->cont.next) - rna_def_struct_function_header_cpp(f, srna, dfunc); + for (ds2 = DefRNA.structs.first; ds2; ds2 = ds2->cont.next) { + srna2 = ds2->srna; + + if (rna_is_collection_functions_struct(collection_func_structs, srna2->identifier)) { + rna_generate_header_class_cpp(ds2, f); + } + } + } - fprintf(f, "};\n\n"); + if (!rna_is_collection_functions_struct(collection_func_structs, srna->identifier)) + rna_generate_header_class_cpp(ds, f); } fprintf(f, "} /* namespace BL */\n"); diff --git a/source/blender/makesrna/intern/rna_action.c b/source/blender/makesrna/intern/rna_action.c index 739b02ef042..07b8072076e 100644 --- a/source/blender/makesrna/intern/rna_action.c +++ b/source/blender/makesrna/intern/rna_action.c @@ -27,6 +27,7 @@ #include <stdlib.h> +#include "RNA_access.h" #include "RNA_define.h" #include "RNA_enum_types.h" @@ -68,12 +69,13 @@ static bActionGroup *rna_Action_groups_new(bAction *act, const char name[]) return action_groups_add_new(act, name); } -static void rna_Action_groups_remove(bAction *act, ReportList *reports, bActionGroup *agrp) +static void rna_Action_groups_remove(bAction *act, ReportList *reports, PointerRNA *agrp_ptr) { + bActionGroup *agrp = agrp_ptr->data; FCurve *fcu, *fcn; /* try to remove the F-Curve from the action */ - if (!BLI_remlink_safe(&act->groups, agrp)) { + if (BLI_remlink_safe(&act->groups, agrp) == FALSE) { BKE_reportf(reports, RPT_ERROR, "Action group '%s' not found in action '%s'", agrp->name, act->id.name + 2); return; } @@ -81,16 +83,16 @@ static void rna_Action_groups_remove(bAction *act, ReportList *reports, bActionG /* move every one one of the group's F-Curves out into the Action again */ for (fcu = agrp->channels.first; (fcu) && (fcu->grp == agrp); fcu = fcn) { fcn = fcu->next; - + /* remove from group */ action_groups_remove_channel(act, fcu); - + /* tack onto the end */ BLI_addtail(&act->curves, fcu); } - - /* XXX, invalidates PyObject */ + MEM_freeN(agrp); + RNA_POINTER_INVALIDATE(agrp_ptr); } static FCurve *rna_Action_fcurve_new(bAction *act, ReportList *reports, const char *data_path, @@ -112,8 +114,9 @@ static FCurve *rna_Action_fcurve_new(bAction *act, ReportList *reports, const ch return verify_fcurve(act, group, NULL, data_path, index, 1); } -static void rna_Action_fcurve_remove(bAction *act, ReportList *reports, FCurve *fcu) +static void rna_Action_fcurve_remove(bAction *act, ReportList *reports, PointerRNA *fcu_ptr) { + FCurve *fcu = fcu_ptr->data; if (fcu->grp) { if (BLI_findindex(&act->groups, fcu->grp) == -1) { BKE_reportf(reports, RPT_ERROR, "F-Curve's action group '%s' not found in action '%s'", @@ -123,6 +126,7 @@ static void rna_Action_fcurve_remove(bAction *act, ReportList *reports, FCurve * action_groups_remove_channel(act, fcu); free_fcurve(fcu); + RNA_POINTER_INVALIDATE(fcu_ptr); } else { if (BLI_findindex(&act->curves, fcu) == -1) { @@ -132,6 +136,7 @@ static void rna_Action_fcurve_remove(bAction *act, ReportList *reports, FCurve * BLI_remlink(&act->curves, fcu); free_fcurve(fcu); + RNA_POINTER_INVALIDATE(fcu_ptr); } } @@ -145,15 +150,16 @@ static TimeMarker *rna_Action_pose_markers_new(bAction *act, const char name[]) return marker; } -static void rna_Action_pose_markers_remove(bAction *act, ReportList *reports, TimeMarker *marker) +static void rna_Action_pose_markers_remove(bAction *act, ReportList *reports, PointerRNA *marker_ptr) { - if (!BLI_remlink_safe(&act->markers, marker)) { + TimeMarker *marker = marker_ptr->data; + if (BLI_remlink_safe(&act->markers, marker) == FALSE) { BKE_reportf(reports, RPT_ERROR, "Timeline marker '%s' not found in action '%s'", marker->name, act->id.name + 2); return; } - /* XXX, invalidates PyObject */ MEM_freeN(marker); + RNA_POINTER_INVALIDATE(marker_ptr); } static PointerRNA rna_Action_active_pose_marker_get(PointerRNA *ptr) @@ -522,7 +528,8 @@ static void rna_def_action_groups(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_ui_description(func, "Remove action group"); RNA_def_function_flag(func, FUNC_USE_REPORTS); parm = RNA_def_pointer(func, "action_group", "ActionGroup", "", "Action group to remove"); - RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); } static void rna_def_action_fcurves(BlenderRNA *brna, PropertyRNA *cprop) @@ -553,7 +560,8 @@ static void rna_def_action_fcurves(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_ui_description(func, "Remove action group"); RNA_def_function_flag(func, FUNC_USE_REPORTS); parm = RNA_def_pointer(func, "fcurve", "FCurve", "", "F-Curve to remove"); - RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); } static void rna_def_action_pose_markers(BlenderRNA *brna, PropertyRNA *cprop) @@ -581,7 +589,8 @@ static void rna_def_action_pose_markers(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_ui_description(func, "Remove a timeline marker"); RNA_def_function_flag(func, FUNC_USE_REPORTS); parm = RNA_def_pointer(func, "marker", "TimelineMarker", "", "Timeline marker to remove"); - RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "TimelineMarker"); diff --git a/source/blender/makesrna/intern/rna_animation.c b/source/blender/makesrna/intern/rna_animation.c index a68898112a0..ce884fa4ecc 100644 --- a/source/blender/makesrna/intern/rna_animation.c +++ b/source/blender/makesrna/intern/rna_animation.c @@ -376,20 +376,23 @@ static KS_Path *rna_KeyingSet_paths_add(KeyingSet *keyingset, ReportList *report return ksp; } -static void rna_KeyingSet_paths_remove(KeyingSet *keyingset, ReportList *reports, KS_Path *ksp) +static void rna_KeyingSet_paths_remove(KeyingSet *keyingset, ReportList *reports, PointerRNA *ksp_ptr) { + KS_Path *ksp = ksp_ptr->data; + /* if data is valid, call the API function for this */ - if (keyingset && ksp) { - /* remove the active path from the KeyingSet */ - BKE_keyingset_free_path(keyingset, ksp); - - /* the active path number will most likely have changed */ - /* TODO: we should get more fancy and actually check if it was removed, but this will do for now */ - keyingset->active_path = 0; - } - else { + if ((keyingset && ksp) == FALSE) { BKE_report(reports, RPT_ERROR, "Keying set path could not be removed"); + return; } + + /* remove the active path from the KeyingSet */ + BKE_keyingset_free_path(keyingset, ksp); + RNA_POINTER_INVALIDATE(ksp_ptr); + + /* the active path number will most likely have changed */ + /* TODO: we should get more fancy and actually check if it was removed, but this will do for now */ + keyingset->active_path = 0; } static void rna_KeyingSet_paths_clear(KeyingSet *keyingset, ReportList *reports) @@ -422,9 +425,17 @@ static NlaTrack *rna_NlaTrack_new(AnimData *adt, bContext *C, NlaTrack *track) return new_track; } -static void rna_NlaTrack_remove(AnimData *adt, bContext *C, NlaTrack *track) +static void rna_NlaTrack_remove(AnimData *adt, bContext *C, ReportList *reports, PointerRNA *track_ptr) { + NlaTrack *track = track_ptr->data; + + if (BLI_findindex(&adt->nla_tracks, track) == -1) { + BKE_reportf(reports, RPT_ERROR, "NlaTrack '%s' can't be removed", track->name); + return; + } + free_nlatrack(&adt->nla_tracks, track); + RNA_POINTER_INVALIDATE(track_ptr); WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_REMOVED, NULL); } @@ -678,7 +689,8 @@ static void rna_def_keyingset_paths(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_flag(func, FUNC_USE_REPORTS); /* path to remove */ parm = RNA_def_pointer(func, "path", "KeyingSetPath", "Path", ""); - RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); /* Remove All Paths */ @@ -783,10 +795,11 @@ static void rna_api_animdata_nla_tracks(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_return(func, parm); func = RNA_def_function(srna, "remove", "rna_NlaTrack_remove"); - RNA_def_function_flag(func, FUNC_USE_CONTEXT); + RNA_def_function_flag(func, FUNC_USE_REPORTS | FUNC_USE_CONTEXT); RNA_def_function_ui_description(func, "Remove a NLA Track"); parm = RNA_def_pointer(func, "track", "NlaTrack", "", "NLA Track to remove"); - RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "NlaTrack"); diff --git a/source/blender/makesrna/intern/rna_armature.c b/source/blender/makesrna/intern/rna_armature.c index 4c188414cf8..4c566d71981 100644 --- a/source/blender/makesrna/intern/rna_armature.c +++ b/source/blender/makesrna/intern/rna_armature.c @@ -29,6 +29,7 @@ #include "BLI_math.h" +#include "RNA_access.h" #include "RNA_define.h" #include "rna_internal.h" @@ -109,8 +110,9 @@ static EditBone *rna_Armature_edit_bone_new(bArmature *arm, ReportList *reports, return ED_armature_edit_bone_add(arm, name); } -static void rna_Armature_edit_bone_remove(bArmature *arm, ReportList *reports, EditBone *ebone) +static void rna_Armature_edit_bone_remove(bArmature *arm, ReportList *reports, PointerRNA *ebone_ptr) { + EditBone *ebone = ebone_ptr->data; if (arm->edbo == NULL) { BKE_reportf(reports, RPT_ERROR, "Armature '%s' not in edit mode, cannot remove an editbone", arm->id.name + 2); return; @@ -122,6 +124,7 @@ static void rna_Armature_edit_bone_remove(bArmature *arm, ReportList *reports, E } ED_armature_edit_bone_remove(arm, ebone); + RNA_POINTER_INVALIDATE(ebone_ptr); } static void rna_Armature_update_layers(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr) @@ -865,7 +868,8 @@ static void rna_def_armature_edit_bones(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_ui_description(func, "Remove an existing bone from the armature"); /* target to remove*/ parm = RNA_def_pointer(func, "bone", "EditBone", "", "EditBone to remove"); - RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); } static void rna_def_armature(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_color.c b/source/blender/makesrna/intern/rna_color.c index f4afaf11d27..f3a3b5c43f8 100644 --- a/source/blender/makesrna/intern/rna_color.c +++ b/source/blender/makesrna/intern/rna_color.c @@ -359,12 +359,27 @@ static CBData *rna_ColorRampElement_new(struct ColorBand *coba, ReportList *repo return element; } -static void rna_ColorRampElement_remove(struct ColorBand *coba, ReportList *reports, CBData *element) +static void rna_ColorRampElement_remove(struct ColorBand *coba, ReportList *reports, PointerRNA *element_ptr) { + CBData *element = element_ptr->data; int index = (int)(element - coba->data); - if (colorband_element_remove(coba, index) == 0) + if (colorband_element_remove(coba, index) == FALSE) { BKE_report(reports, RPT_ERROR, "Element not found in element collection or last element"); + return; + } + RNA_POINTER_INVALIDATE(element_ptr); +} + +void rna_CurveMap_remove_point(CurveMap *cuma, ReportList *reports, PointerRNA *point_ptr) +{ + CurveMapPoint *point = point_ptr->data; + if (curvemap_remove_point(cuma, point) == FALSE) { + BKE_report(reports, RPT_ERROR, "Unable to remove curve point"); + return; + } + + RNA_POINTER_INVALIDATE(point_ptr); } static void rna_Scopes_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) @@ -589,10 +604,12 @@ static void rna_def_curvemap_points_api(BlenderRNA *brna, PropertyRNA *cprop) parm = RNA_def_pointer(func, "point", "CurveMapPoint", "", "New point"); RNA_def_function_return(func, parm); - func = RNA_def_function(srna, "remove", "curvemap_remove_point"); + func = RNA_def_function(srna, "remove", "rna_CurveMap_remove_point"); + RNA_def_function_flag(func, FUNC_USE_REPORTS); RNA_def_function_ui_description(func, "Delete point from CurveMap"); parm = RNA_def_pointer(func, "point", "CurveMapPoint", "", "PointElement to remove"); - RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); } static void rna_def_curvemap(BlenderRNA *brna) @@ -741,7 +758,8 @@ static void rna_def_color_ramp_element_api(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_ui_description(func, "Delete element from ColorRamp"); RNA_def_function_flag(func, FUNC_USE_REPORTS); parm = RNA_def_pointer(func, "element", "ColorRampElement", "", "Element to remove"); - RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); } static void rna_def_color_ramp(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c index 354d7bae1ed..35699c6ef3f 100644 --- a/source/blender/makesrna/intern/rna_curve.c +++ b/source/blender/makesrna/intern/rna_curve.c @@ -26,6 +26,7 @@ #include <stdlib.h> +#include "RNA_access.h" #include "RNA_define.h" #include "rna_internal.h" @@ -573,20 +574,18 @@ static Nurb *rna_Curve_spline_new(Curve *cu, int type) return nu; } -static void rna_Curve_spline_remove(Curve *cu, ReportList *reports, Nurb *nu) +static void rna_Curve_spline_remove(Curve *cu, ReportList *reports, PointerRNA *nu_ptr) { - int found = 0; + Nurb *nu = nu_ptr->data; ListBase *nurbs = BKE_curve_nurbs_get(cu); - found = BLI_remlink_safe(nurbs, nu); - - if (!found) { + if (BLI_remlink_safe(nurbs, nu) == FALSE) { BKE_reportf(reports, RPT_ERROR, "Curve '%s' does not contain spline given", cu->id.name + 2); return; } BKE_nurb_free(nu); - /* invalidate pointer!, no can do */ + RNA_POINTER_INVALIDATE(nu_ptr); DAG_id_tag_update(&cu->id, OB_RECALC_DATA); WM_main_add_notifier(NC_GEOM | ND_DATA, NULL); @@ -1171,7 +1170,8 @@ static void rna_def_curve_spline_points(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_ui_description(func, "Remove a spline from a curve"); RNA_def_function_flag(func, FUNC_USE_REPORTS); parm = RNA_def_pointer(func, "spline", "Spline", "", "The spline to remove"); - RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); #endif } @@ -1198,7 +1198,8 @@ static void rna_def_curve_spline_bezpoints(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_ui_description(func, "Remove a spline from a curve"); RNA_def_function_flag(func, FUNC_USE_REPORTS); parm = RNA_def_pointer(func, "spline", "Spline", "", "The spline to remove"); - RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); #endif } @@ -1227,7 +1228,8 @@ static void rna_def_curve_splines(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_ui_description(func, "Remove a spline from a curve"); RNA_def_function_flag(func, FUNC_USE_REPORTS); parm = RNA_def_pointer(func, "spline", "Spline", "", "The spline to remove"); - RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); func = RNA_def_function(srna, "clear", "rna_Curve_spline_clear"); RNA_def_function_ui_description(func, "Remove all spline from a curve"); diff --git a/source/blender/makesrna/intern/rna_define.c b/source/blender/makesrna/intern/rna_define.c index ffeb221a847..bb1ecea6a24 100644 --- a/source/blender/makesrna/intern/rna_define.c +++ b/source/blender/makesrna/intern/rna_define.c @@ -981,8 +981,10 @@ PropertyRNA *RNA_def_property(StructOrFunctionRNA *cont_, const char *identifier sprop->defaultvalue = ""; break; } - case PROP_ENUM: case PROP_POINTER: + prop->flag |= PROP_THICK_WRAP; /* needed for default behavior when PROP_RNAPTR is set */ + break; + case PROP_ENUM: case PROP_COLLECTION: break; default: @@ -2810,14 +2812,26 @@ int rna_parameter_size(PropertyRNA *parm) { #ifdef RNA_RUNTIME if (parm->flag & PROP_RNAPTR) - return sizeof(PointerRNA); + if (parm->flag & PROP_THICK_WRAP) { + return sizeof(PointerRNA); + } + else { + return sizeof(PointerRNA *); + } else return sizeof(void *); #else - if (parm->flag & PROP_RNAPTR) - return sizeof(PointerRNA); - else + if (parm->flag & PROP_RNAPTR) { + if (parm->flag & PROP_THICK_WRAP) { + return sizeof(PointerRNA); + } + else { + return sizeof(PointerRNA *); + } + } + else { return sizeof(void *); + } #endif } case PROP_COLLECTION: diff --git a/source/blender/makesrna/intern/rna_fcurve.c b/source/blender/makesrna/intern/rna_fcurve.c index d899b5833bb..4250acf5848 100644 --- a/source/blender/makesrna/intern/rna_fcurve.c +++ b/source/blender/makesrna/intern/rna_fcurve.c @@ -409,14 +409,16 @@ static DriverVar *rna_Driver_new_variable(ChannelDriver *driver) return driver_add_new_variable(driver); } -static void rna_Driver_remove_variable(ChannelDriver *driver, ReportList *reports, DriverVar *dvar) +static void rna_Driver_remove_variable(ChannelDriver *driver, ReportList *reports, PointerRNA *dvar_ptr) { + DriverVar *dvar = dvar_ptr->data; if (BLI_findindex(&driver->variables, dvar) == -1) { BKE_report(reports, RPT_ERROR, "Variable does not exist in this driver"); return; } driver_free_variable(driver, dvar); + RNA_POINTER_INVALIDATE(dvar_ptr); } @@ -438,13 +440,16 @@ static FModifier *rna_FCurve_modifiers_new(FCurve *fcu, int type) return add_fmodifier(&fcu->modifiers, type); } -static void rna_FCurve_modifiers_remove(FCurve *fcu, ReportList *reports, FModifier *fcm) +static void rna_FCurve_modifiers_remove(FCurve *fcu, ReportList *reports, PointerRNA *fcm_ptr) { + FModifier *fcm = fcm_ptr->data; if (BLI_findindex(&fcu->modifiers, fcm) == -1) { BKE_reportf(reports, RPT_ERROR, "F-Curve modifier '%s' not found in F-Curve", fcm->name); return; } + remove_fmodifier(&fcu->modifiers, fcm); + RNA_POINTER_INVALIDATE(fcm_ptr); } static void rna_FModifier_active_set(PointerRNA *ptr, int UNUSED(value)) @@ -610,8 +615,9 @@ static void rna_FKeyframe_points_add(FCurve *fcu, int tot) } } -static void rna_FKeyframe_points_remove(FCurve *fcu, ReportList *reports, BezTriple *bezt, int do_fast) +static void rna_FKeyframe_points_remove(FCurve *fcu, ReportList *reports, PointerRNA *bezt_ptr, int do_fast) { + BezTriple *bezt = bezt_ptr->data; int index = (int)(bezt - fcu->bezt); if (index < 0 || index >= fcu->totvert) { BKE_report(reports, RPT_ERROR, "Keyframe not in F-Curve"); @@ -619,6 +625,7 @@ static void rna_FKeyframe_points_remove(FCurve *fcu, ReportList *reports, BezTri } delete_fcurve_key(fcu, index, !do_fast); + RNA_POINTER_INVALIDATE(bezt_ptr); } static void rna_fcurve_range(FCurve *fcu, float range[2]) @@ -1263,7 +1270,8 @@ static void rna_def_channeldriver_variables(BlenderRNA *brna, PropertyRNA *cprop RNA_def_function_flag(func, FUNC_USE_REPORTS); /* target to remove */ parm = RNA_def_pointer(func, "variable", "DriverVariable", "", "Variable to remove from the driver"); - RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); } static void rna_def_channeldriver(BlenderRNA *brna) @@ -1458,7 +1466,8 @@ static void rna_def_fcurve_modifiers(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_ui_description(func, "Remove a modifier from this F-Curve"); /* modifier to remove */ parm = RNA_def_pointer(func, "modifier", "FModifier", "", "Removed modifier"); - RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); } /* fcurve.keyframe_points */ @@ -1503,7 +1512,8 @@ static void rna_def_fcurve_keyframe_points(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_ui_description(func, "Remove keyframe from an F-Curve"); RNA_def_function_flag(func, FUNC_USE_REPORTS); parm = RNA_def_pointer(func, "keyframe", "Keyframe", "", "Keyframe to remove"); - RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); /* optional */ RNA_def_boolean(func, "fast", 0, "Fast", "Fast keyframe removal to avoid recalculating the curve each time"); } diff --git a/source/blender/makesrna/intern/rna_gpencil.c b/source/blender/makesrna/intern/rna_gpencil.c index 55e7064390d..b3c1f4dd505 100644 --- a/source/blender/makesrna/intern/rna_gpencil.c +++ b/source/blender/makesrna/intern/rna_gpencil.c @@ -27,6 +27,7 @@ #include <stdlib.h> +#include "RNA_access.h" #include "RNA_define.h" #include "rna_internal.h" @@ -162,14 +163,16 @@ static bGPDstroke *rna_GPencil_stroke_new(bGPDframe *frame) return stroke; } -static void rna_GPencil_stroke_remove(bGPDframe *frame, ReportList *reports, bGPDstroke *stroke) +static void rna_GPencil_stroke_remove(bGPDframe *frame, ReportList *reports, PointerRNA *stroke_ptr) { + bGPDstroke *stroke = stroke_ptr->data; if (BLI_findindex(&frame->strokes, stroke) == -1) { BKE_report(reports, RPT_ERROR, "Stroke not found in grease pencil frame"); return; } - + BLI_freelinkN(&frame->strokes, stroke); + RNA_POINTER_INVALIDATE(stroke_ptr); WM_main_add_notifier(NC_GPENCIL | NA_EDITED, NULL); } @@ -190,14 +193,16 @@ static bGPDframe *rna_GPencil_frame_new(bGPDlayer *layer, ReportList *reports, i return frame; } -static void rna_GPencil_frame_remove(bGPDlayer *layer, ReportList *reports, bGPDframe *frame) +static void rna_GPencil_frame_remove(bGPDlayer *layer, ReportList *reports, PointerRNA *frame_ptr) { + bGPDframe *frame = frame_ptr->data; if (BLI_findindex(&layer->frames, frame) == -1) { BKE_report(reports, RPT_ERROR, "Frame not found in grease pencil layer"); return; } - + gpencil_layer_delframe(layer, frame); + RNA_POINTER_INVALIDATE(frame_ptr); WM_main_add_notifier(NC_GPENCIL | NA_EDITED, NULL); } @@ -226,14 +231,16 @@ static bGPDlayer *rna_GPencil_layer_new(bGPdata *gpd, const char *name, int seta return gl; } -static void rna_GPencil_layer_remove(bGPdata *gpd, ReportList *reports, bGPDlayer *layer) +static void rna_GPencil_layer_remove(bGPdata *gpd, ReportList *reports, PointerRNA *layer_ptr) { + bGPDlayer *layer = layer_ptr->data; if (BLI_findindex(&gpd->layers, layer) == -1) { BKE_report(reports, RPT_ERROR, "Layer not found in grease pencil data"); return; } - + gpencil_layer_delete(gpd, layer); + RNA_POINTER_INVALIDATE(layer_ptr); WM_main_add_notifier(NC_GPENCIL | ND_DATA | NA_EDITED, NULL); } @@ -357,7 +364,8 @@ static void rna_def_gpencil_strokes_api(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_ui_description(func, "Remove a grease pencil frame"); RNA_def_function_flag(func, FUNC_USE_REPORTS); parm = RNA_def_pointer(func, "stroke", "GPencilStroke", "Stroke", "The stroke to remove"); - RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); } static void rna_def_gpencil_frame(BlenderRNA *brna) @@ -421,7 +429,8 @@ static void rna_def_gpencil_frames_api(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_ui_description(func, "Remove a grease pencil frame"); RNA_def_function_flag(func, FUNC_USE_REPORTS); parm = RNA_def_pointer(func, "frame", "GPencilFrame", "Frame", "The frame to remove"); - RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); func = RNA_def_function(srna, "copy", "rna_GPencil_frame_copy"); RNA_def_function_ui_description(func, "Copy a grease pencil frame"); @@ -558,7 +567,7 @@ static void rna_def_gpencil_layers_api(BlenderRNA *brna, PropertyRNA *cprop) func = RNA_def_function(srna, "new", "rna_GPencil_layer_new"); RNA_def_function_ui_description(func, "Add a new grease pencil layer"); - parm = RNA_def_string(func, "name", "GPencilLayer", MAX_NAME, "Name", "Name of the layer"); + parm = RNA_def_string(func, "name", "GPencilLayer", MAX_NAME, "Name", "Name of the layer"); RNA_def_property_flag(parm, PROP_REQUIRED); RNA_def_boolean(func, "set_active", 0, "Set Active", "Set the newly created layer to the active layer"); parm = RNA_def_pointer(func, "layer", "GPencilLayer", "", "The newly created layer"); @@ -568,7 +577,8 @@ static void rna_def_gpencil_layers_api(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_ui_description(func, "Remove a grease pencil layer"); RNA_def_function_flag(func, FUNC_USE_REPORTS); parm = RNA_def_pointer(func, "layer", "GPencilLayer", "", "The layer to remove"); - RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "GreasePencil"); diff --git a/source/blender/makesrna/intern/rna_main.c b/source/blender/makesrna/intern/rna_main.c index 78e0fde5715..7783a64bf9f 100644 --- a/source/blender/makesrna/intern/rna_main.c +++ b/source/blender/makesrna/intern/rna_main.c @@ -51,7 +51,7 @@ static int rna_Main_is_dirty_get(PointerRNA *ptr) /* XXX, not totally nice to do it this way, should store in main ? */ Main *bmain = (Main *)ptr->data; wmWindowManager *wm; - for (wm = bmain->wm.first; wm; wm = wm->id.next) { + if ((wm = bmain->wm.first)) { return !wm->file_saved; } diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c index e38b64a09db..5edb5da3e7c 100644 --- a/source/blender/makesrna/intern/rna_main_api.c +++ b/source/blender/makesrna/intern/rna_main_api.c @@ -106,39 +106,43 @@ static Camera *rna_Main_cameras_new(Main *UNUSED(bmain), const char *name) id_us_min(id); return (Camera *)id; } -static void rna_Main_cameras_remove(Main *bmain, ReportList *reports, struct Camera *camera) +static void rna_Main_cameras_remove(Main *bmain, ReportList *reports, PointerRNA *camera_ptr) { - if (ID_REAL_USERS(camera) <= 0) + Camera *camera = camera_ptr->data; + if (ID_REAL_USERS(camera) <= 0) { BKE_libblock_free(&bmain->camera, camera); - else + RNA_POINTER_INVALIDATE(camera_ptr); + } + else { BKE_reportf(reports, RPT_ERROR, "Camera '%s' must have zero users to be removed, found %d", camera->id.name + 2, ID_REAL_USERS(camera)); - - /* XXX python now has invalid pointer? */ + } } static Scene *rna_Main_scenes_new(Main *UNUSED(bmain), const char *name) { return BKE_scene_add(name); } -static void rna_Main_scenes_remove(Main *bmain, bContext *C, ReportList *reports, struct Scene *scene) +static void rna_Main_scenes_remove(Main *bmain, bContext *C, ReportList *reports, PointerRNA *scene_ptr) { /* don't call BKE_libblock_free(...) directly */ - Scene *newscene; + Scene *scene = scene_ptr->data; + Scene *scene_new; + + if ((scene_new = scene->id.prev) || + (scene_new = scene->id.next)) + { + bScreen *sc = CTX_wm_screen(C); + if (sc->scene == scene) { + ED_screen_set_scene(C, sc, scene_new); + } - if (scene->id.prev) - newscene = scene->id.prev; - else if (scene->id.next) - newscene = scene->id.next; + BKE_scene_unlink(bmain, scene, scene_new); + RNA_POINTER_INVALIDATE(scene_ptr); + } else { BKE_reportf(reports, RPT_ERROR, "Scene '%s' is the last, cannot be removed", scene->id.name + 2); - return; } - - if (CTX_wm_screen(C)->scene == scene) - ED_screen_set_scene(C, CTX_wm_screen(C), newscene); - - BKE_scene_unlink(bmain, scene, newscene); } static Object *rna_Main_objects_new(Main *UNUSED(bmain), ReportList *reports, const char *name, ID *data) @@ -152,7 +156,7 @@ static Object *rna_Main_objects_new(Main *UNUSED(bmain), ReportList *reports, co type = OB_MESH; break; case ID_CU: - type = BKE_curve_type_get((struct Curve *)data); + type = BKE_curve_type_get((Curve *)data); break; case ID_MB: type = OB_MBALL; @@ -195,11 +199,13 @@ static Object *rna_Main_objects_new(Main *UNUSED(bmain), ReportList *reports, co return ob; } -static void rna_Main_objects_remove(Main *bmain, ReportList *reports, struct Object *object) +static void rna_Main_objects_remove(Main *bmain, ReportList *reports, PointerRNA *object_ptr) { + Object *object = object_ptr->data; if (ID_REAL_USERS(object) <= 0) { BKE_object_unlink(object); /* needed or ID pointers to this are not cleared */ BKE_libblock_free(&bmain->object, object); + RNA_POINTER_INVALIDATE(object_ptr); } else { BKE_reportf(reports, RPT_ERROR, "Object '%s' must have zero users to be removed, found %d", @@ -213,15 +219,17 @@ static Material *rna_Main_materials_new(Main *UNUSED(bmain), const char *name) id_us_min(id); return (Material *)id; } -static void rna_Main_materials_remove(Main *bmain, ReportList *reports, struct Material *material) +static void rna_Main_materials_remove(Main *bmain, ReportList *reports, PointerRNA *material_ptr) { - if (ID_REAL_USERS(material) <= 0) + Material *material = material_ptr->data; + if (ID_REAL_USERS(material) <= 0) { BKE_libblock_free(&bmain->mat, material); - else + RNA_POINTER_INVALIDATE(material_ptr); + } + else { BKE_reportf(reports, RPT_ERROR, "Material '%s' must have zero users to be removed, found %d", material->id.name + 2, ID_REAL_USERS(material)); - - /* XXX python now has invalid pointer? */ + } } static bNodeTree *rna_Main_nodetree_new(Main *UNUSED(bmain), const char *name, int type) @@ -231,15 +239,17 @@ static bNodeTree *rna_Main_nodetree_new(Main *UNUSED(bmain), const char *name, i id_us_min(&tree->id); return tree; } -static void rna_Main_nodetree_remove(Main *bmain, ReportList *reports, struct bNodeTree *tree) +static void rna_Main_nodetree_remove(Main *bmain, ReportList *reports, PointerRNA *tree_ptr) { - if (ID_REAL_USERS(tree) <= 0) + bNodeTree *tree = tree_ptr->data; + if (ID_REAL_USERS(tree) <= 0) { BKE_libblock_free(&bmain->nodetree, tree); - else + RNA_POINTER_INVALIDATE(tree_ptr); + } + else { BKE_reportf(reports, RPT_ERROR, "Node tree '%s' must have zero users to be removed, found %d", tree->id.name + 2, ID_REAL_USERS(tree)); - - /* XXX python now has invalid pointer? */ + } } static Mesh *rna_Main_meshes_new(Main *UNUSED(bmain), const char *name) @@ -248,15 +258,17 @@ static Mesh *rna_Main_meshes_new(Main *UNUSED(bmain), const char *name) id_us_min(&me->id); return me; } -static void rna_Main_meshes_remove(Main *bmain, ReportList *reports, Mesh *mesh) +static void rna_Main_meshes_remove(Main *bmain, ReportList *reports, PointerRNA *mesh_ptr) { - if (ID_REAL_USERS(mesh) <= 0) + Mesh *mesh = mesh_ptr->data; + if (ID_REAL_USERS(mesh) <= 0) { BKE_libblock_free(&bmain->mesh, mesh); - else + RNA_POINTER_INVALIDATE(mesh_ptr); + } + else { BKE_reportf(reports, RPT_ERROR, "Mesh '%s' must have zero users to be removed, found %d", mesh->id.name + 2, ID_REAL_USERS(mesh)); - - /* XXX python now has invalid pointer? */ + } } static Lamp *rna_Main_lamps_new(Main *UNUSED(bmain), const char *name, int type) @@ -266,15 +278,17 @@ static Lamp *rna_Main_lamps_new(Main *UNUSED(bmain), const char *name, int type) id_us_min(&lamp->id); return lamp; } -static void rna_Main_lamps_remove(Main *bmain, ReportList *reports, Lamp *lamp) +static void rna_Main_lamps_remove(Main *bmain, ReportList *reports, PointerRNA *lamp_ptr) { - if (ID_REAL_USERS(lamp) <= 0) + Lamp *lamp = lamp_ptr->data; + if (ID_REAL_USERS(lamp) <= 0) { BKE_libblock_free(&bmain->lamp, lamp); - else + RNA_POINTER_INVALIDATE(lamp_ptr); + } + else { BKE_reportf(reports, RPT_ERROR, "Lamp '%s' must have zero users to be removed, found %d", lamp->id.name + 2, ID_REAL_USERS(lamp)); - - /* XXX python now has invalid pointer? */ + } } static Image *rna_Main_images_new(Main *UNUSED(bmain), const char *name, int width, int height, int alpha, int float_buffer) @@ -291,21 +305,24 @@ static Image *rna_Main_images_load(Main *UNUSED(bmain), ReportList *reports, con errno = 0; ima = BKE_image_load(filepath); - if (!ima) + if (!ima) { BKE_reportf(reports, RPT_ERROR, "Cannot read '%s': %s", filepath, errno ? strerror(errno) : TIP_("unsupported image format")); + } return ima; } -static void rna_Main_images_remove(Main *bmain, ReportList *reports, Image *image) +static void rna_Main_images_remove(Main *bmain, ReportList *reports, PointerRNA *image_ptr) { - if (ID_REAL_USERS(image) <= 0) + Image *image = image_ptr->data; + if (ID_REAL_USERS(image) <= 0) { BKE_libblock_free(&bmain->image, image); - else + RNA_POINTER_INVALIDATE(image_ptr); + } + else { BKE_reportf(reports, RPT_ERROR, "Image '%s' must have zero users to be removed, found %d", image->id.name + 2, ID_REAL_USERS(image)); - - /* XXX python now has invalid pointer? */ + } } static Lattice *rna_Main_lattices_new(Main *UNUSED(bmain), const char *name) @@ -314,13 +331,17 @@ static Lattice *rna_Main_lattices_new(Main *UNUSED(bmain), const char *name) id_us_min(<->id); return lt; } -static void rna_Main_lattices_remove(Main *bmain, ReportList *reports, struct Lattice *lt) +static void rna_Main_lattices_remove(Main *bmain, ReportList *reports, PointerRNA *lt_ptr) { - if (ID_REAL_USERS(lt) <= 0) + Lattice *lt = lt_ptr->data; + if (ID_REAL_USERS(lt) <= 0) { BKE_libblock_free(&bmain->latt, lt); - else + RNA_POINTER_INVALIDATE(lt_ptr); + } + else { BKE_reportf(reports, RPT_ERROR, "Lattice '%s' must have zero users to be removed, found %d", lt->id.name + 2, ID_REAL_USERS(lt)); + } } static Curve *rna_Main_curves_new(Main *UNUSED(bmain), const char *name, int type) @@ -329,13 +350,17 @@ static Curve *rna_Main_curves_new(Main *UNUSED(bmain), const char *name, int typ id_us_min(&cu->id); return cu; } -static void rna_Main_curves_remove(Main *bmain, ReportList *reports, struct Curve *cu) +static void rna_Main_curves_remove(Main *bmain, ReportList *reports, PointerRNA *cu_ptr) { - if (ID_REAL_USERS(cu) <= 0) + Curve *cu = cu_ptr->data; + if (ID_REAL_USERS(cu) <= 0) { BKE_libblock_free(&bmain->curve, cu); - else + RNA_POINTER_INVALIDATE(cu_ptr); + } + else { BKE_reportf(reports, RPT_ERROR, "Curve '%s' must have zero users to be removed, found %d", cu->id.name + 2, ID_REAL_USERS(cu)); + } } static MetaBall *rna_Main_metaballs_new(Main *UNUSED(bmain), const char *name) @@ -344,13 +369,17 @@ static MetaBall *rna_Main_metaballs_new(Main *UNUSED(bmain), const char *name) id_us_min(&mb->id); return mb; } -static void rna_Main_metaballs_remove(Main *bmain, ReportList *reports, struct MetaBall *mb) +static void rna_Main_metaballs_remove(Main *bmain, ReportList *reports, PointerRNA *mb_ptr) { - if (ID_REAL_USERS(mb) <= 0) + MetaBall *mb = mb_ptr->data; + if (ID_REAL_USERS(mb) <= 0) { BKE_libblock_free(&bmain->mball, mb); - else + RNA_POINTER_INVALIDATE(mb_ptr); + } + else { BKE_reportf(reports, RPT_ERROR, "Metaball '%s' must have zero users to be removed, found %d", mb->id.name + 2, ID_REAL_USERS(mb)); + } } static VFont *rna_Main_fonts_load(Main *bmain, ReportList *reports, const char *filepath) @@ -367,15 +396,17 @@ static VFont *rna_Main_fonts_load(Main *bmain, ReportList *reports, const char * return font; } -static void rna_Main_fonts_remove(Main *bmain, ReportList *reports, VFont *vfont) +static void rna_Main_fonts_remove(Main *bmain, ReportList *reports, PointerRNA *vfont_ptr) { - if (ID_REAL_USERS(vfont) <= 0) + VFont *vfont = vfont_ptr->data; + if (ID_REAL_USERS(vfont) <= 0) { BKE_libblock_free(&bmain->vfont, vfont); - else + RNA_POINTER_INVALIDATE(vfont_ptr); + } + else { BKE_reportf(reports, RPT_ERROR, "Font '%s' must have zero users to be removed, found %d", vfont->id.name + 2, ID_REAL_USERS(vfont)); - - /* XXX python now has invalid pointer? */ + } } static Tex *rna_Main_textures_new(Main *UNUSED(bmain), const char *name, int type) @@ -385,13 +416,17 @@ static Tex *rna_Main_textures_new(Main *UNUSED(bmain), const char *name, int typ id_us_min(&tex->id); return tex; } -static void rna_Main_textures_remove(Main *bmain, ReportList *reports, struct Tex *tex) +static void rna_Main_textures_remove(Main *bmain, ReportList *reports, PointerRNA *tex_ptr) { - if (ID_REAL_USERS(tex) <= 0) + Tex *tex = tex_ptr->data; + if (ID_REAL_USERS(tex) <= 0) { BKE_libblock_free(&bmain->tex, tex); - else + RNA_POINTER_INVALIDATE(tex_ptr); + } + else { BKE_reportf(reports, RPT_ERROR, "Texture '%s' must have zero users to be removed, found %d", tex->id.name + 2, ID_REAL_USERS(tex)); + } } static Brush *rna_Main_brushes_new(Main *UNUSED(bmain), const char *name) @@ -400,13 +435,17 @@ static Brush *rna_Main_brushes_new(Main *UNUSED(bmain), const char *name) id_us_min(&brush->id); return brush; } -static void rna_Main_brushes_remove(Main *bmain, ReportList *reports, struct Brush *brush) +static void rna_Main_brushes_remove(Main *bmain, ReportList *reports, PointerRNA *brush_ptr) { - if (ID_REAL_USERS(brush) <= 0) + Brush *brush = brush_ptr->data; + if (ID_REAL_USERS(brush) <= 0) { BKE_libblock_free(&bmain->brush, brush); - else + RNA_POINTER_INVALIDATE(brush_ptr); + } + else { BKE_reportf(reports, RPT_ERROR, "Brush '%s' must have zero users to be removed, found %d", brush->id.name + 2, ID_REAL_USERS(brush)); + } } static World *rna_Main_worlds_new(Main *UNUSED(bmain), const char *name) @@ -415,24 +454,29 @@ static World *rna_Main_worlds_new(Main *UNUSED(bmain), const char *name) id_us_min(&world->id); return world; } -static void rna_Main_worlds_remove(Main *bmain, ReportList *reports, struct World *world) +static void rna_Main_worlds_remove(Main *bmain, ReportList *reports, PointerRNA *world_ptr) { - if (ID_REAL_USERS(world) <= 0) + Group *world = world_ptr->data; + if (ID_REAL_USERS(world) <= 0) { BKE_libblock_free(&bmain->world, world); - else + RNA_POINTER_INVALIDATE(world_ptr); + } + else { BKE_reportf(reports, RPT_ERROR, "World '%s' must have zero users to be removed, found %d", world->id.name + 2, ID_REAL_USERS(world)); + } } static Group *rna_Main_groups_new(Main *UNUSED(bmain), const char *name) { return add_group(name); } -static void rna_Main_groups_remove(Main *bmain, Group *group) +static void rna_Main_groups_remove(Main *bmain, PointerRNA *group_ptr) { + Group *group = group_ptr->data; BKE_group_unlink(group); BKE_libblock_free(&bmain->group, group); - /* XXX python now has invalid pointer? */ + RNA_POINTER_INVALIDATE(group_ptr); } static Speaker *rna_Main_speakers_new(Main *UNUSED(bmain), const char *name) @@ -441,26 +485,29 @@ static Speaker *rna_Main_speakers_new(Main *UNUSED(bmain), const char *name) id_us_min(&speaker->id); return speaker; } -static void rna_Main_speakers_remove(Main *bmain, ReportList *reports, Speaker *speaker) +static void rna_Main_speakers_remove(Main *bmain, ReportList *reports, PointerRNA *speaker_ptr) { - if (ID_REAL_USERS(speaker) <= 0) + Speaker *speaker = speaker_ptr->data; + if (ID_REAL_USERS(speaker) <= 0) { BKE_libblock_free(&bmain->speaker, speaker); - else + RNA_POINTER_INVALIDATE(speaker_ptr); + } + else { BKE_reportf(reports, RPT_ERROR, "Speaker '%s' must have zero users to be removed, found %d", speaker->id.name + 2, ID_REAL_USERS(speaker)); - - /* XXX python now has invalid pointer? */ + } } static Text *rna_Main_texts_new(Main *UNUSED(bmain), const char *name) { return BKE_text_add(name); } -static void rna_Main_texts_remove(Main *bmain, Text *text) +static void rna_Main_texts_remove(Main *bmain, PointerRNA *text_ptr) { + Text *text = text_ptr->data; BKE_text_unlink(bmain, text); BKE_libblock_free(&bmain->text, text); - /* XXX python now has invalid pointer? */ + RNA_POINTER_INVALIDATE(text_ptr); } static Text *rna_Main_texts_load(Main *bmain, ReportList *reports, const char *filepath) @@ -483,15 +530,17 @@ static bArmature *rna_Main_armatures_new(Main *UNUSED(bmain), const char *name) id_us_min(&arm->id); return arm; } -static void rna_Main_armatures_remove(Main *bmain, ReportList *reports, bArmature *arm) +static void rna_Main_armatures_remove(Main *bmain, ReportList *reports, PointerRNA *arm_ptr) { - if (ID_REAL_USERS(arm) <= 0) + bArmature *arm = arm_ptr->data; + if (ID_REAL_USERS(arm) <= 0) { BKE_libblock_free(&bmain->armature, arm); - else + RNA_POINTER_INVALIDATE(arm_ptr); + } + else { BKE_reportf(reports, RPT_ERROR, "Armature '%s' must have zero users to be removed, found %d", arm->id.name + 2, ID_REAL_USERS(arm)); - - /* XXX python now has invalid pointer? */ + } } static bAction *rna_Main_actions_new(Main *UNUSED(bmain), const char *name) @@ -501,15 +550,17 @@ static bAction *rna_Main_actions_new(Main *UNUSED(bmain), const char *name) act->id.flag &= ~LIB_FAKEUSER; return act; } -static void rna_Main_actions_remove(Main *bmain, ReportList *reports, bAction *act) +static void rna_Main_actions_remove(Main *bmain, ReportList *reports, PointerRNA *act_ptr) { - if (ID_REAL_USERS(act) <= 0) + bAction *act = act_ptr->data; + if (ID_REAL_USERS(act) <= 0) { BKE_libblock_free(&bmain->action, act); - else + RNA_POINTER_INVALIDATE(act_ptr); + } + else { BKE_reportf(reports, RPT_ERROR, "Action '%s' must have zero users to be removed, found %d", act->id.name + 2, ID_REAL_USERS(act)); - - /* XXX python now has invalid pointer? */ + } } static ParticleSettings *rna_Main_particles_new(Main *bmain, const char *name) @@ -518,15 +569,17 @@ static ParticleSettings *rna_Main_particles_new(Main *bmain, const char *name) id_us_min(&part->id); return part; } -static void rna_Main_particles_remove(Main *bmain, ReportList *reports, ParticleSettings *part) +static void rna_Main_particles_remove(Main *bmain, ReportList *reports, PointerRNA *part_ptr) { - if (ID_REAL_USERS(part) <= 0) + ParticleSettings *part = part_ptr->data; + if (ID_REAL_USERS(part) <= 0) { BKE_libblock_free(&bmain->particle, part); - else + RNA_POINTER_INVALIDATE(part_ptr); + } + else { BKE_reportf(reports, RPT_ERROR, "Particle settings '%s' must have zero users to be removed, found %d", part->id.name + 2, ID_REAL_USERS(part)); - - /* XXX python now has invalid pointer? */ + } } static MovieClip *rna_Main_movieclip_load(Main *UNUSED(bmain), ReportList *reports, const char *filepath) @@ -543,11 +596,12 @@ static MovieClip *rna_Main_movieclip_load(Main *UNUSED(bmain), ReportList *repor return clip; } -static void rna_Main_movieclips_remove(Main *bmain, MovieClip *clip) +static void rna_Main_movieclips_remove(Main *bmain, PointerRNA *clip_ptr) { + MovieClip *clip = clip_ptr->data; BKE_movieclip_unlink(bmain, clip); BKE_libblock_free(&bmain->movieclip, clip); - /* XXX python now has invalid pointer? */ + RNA_POINTER_INVALIDATE(clip_ptr); } static Mask *rna_Main_mask_new(Main *UNUSED(bmain), const char *name) @@ -559,24 +613,25 @@ static Mask *rna_Main_mask_new(Main *UNUSED(bmain), const char *name) return mask; } -static void rna_Main_masks_remove(Main *bmain, Mask *mask) +static void rna_Main_masks_remove(Main *bmain, PointerRNA *mask_ptr) { + Mask *mask = mask_ptr->data; BKE_mask_free(bmain, mask); BKE_libblock_free(&bmain->mask, mask); - /* XXX python now has invalid pointer? */ + RNA_POINTER_INVALIDATE(mask_ptr); } -static void rna_Main_grease_pencil_remove(Main *bmain, ReportList *reports, bGPdata *gpd) +static void rna_Main_grease_pencil_remove(Main *bmain, ReportList *reports, PointerRNA *gpd_ptr) { + bGPdata *gpd = gpd_ptr->data; if (ID_REAL_USERS(gpd) <= 0) { BKE_gpencil_free(gpd); BKE_libblock_free(&bmain->gpencil, gpd); + RNA_POINTER_INVALIDATE(gpd_ptr); } else BKE_reportf(reports, RPT_ERROR, "Grease pencil '%s' must have zero users to be removed, found %d", gpd->id.name + 2, ID_REAL_USERS(gpd)); - - /* XXX python now has invalid pointer? */ } FreestyleLineStyle *rna_Main_linestyles_new(Main *bmain, const char* name) @@ -700,7 +755,8 @@ void RNA_def_main_cameras(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_flag(func, FUNC_USE_REPORTS); RNA_def_function_ui_description(func, "Remove a camera from the current blendfile"); parm = RNA_def_pointer(func, "camera", "Camera", "", "Camera to remove"); - RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); func = RNA_def_function(srna, "tag", "rna_Main_cameras_tag"); parm = RNA_def_boolean(func, "value", 0, "Value", ""); @@ -735,7 +791,8 @@ void RNA_def_main_scenes(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_flag(func, FUNC_USE_CONTEXT | FUNC_USE_REPORTS); RNA_def_function_ui_description(func, "Remove a scene from the current blendfile"); parm = RNA_def_pointer(func, "scene", "Scene", "", "Scene to remove"); - RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); func = RNA_def_function(srna, "tag", "rna_Main_scenes_tag"); parm = RNA_def_boolean(func, "value", 0, "Value", ""); @@ -774,7 +831,8 @@ void RNA_def_main_objects(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_ui_description(func, "Remove a object from the current blendfile"); RNA_def_function_flag(func, FUNC_USE_REPORTS); parm = RNA_def_pointer(func, "object", "Object", "", "Object to remove"); - RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); func = RNA_def_function(srna, "tag", "rna_Main_objects_tag"); parm = RNA_def_boolean(func, "value", 0, "Value", ""); @@ -809,7 +867,8 @@ void RNA_def_main_materials(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_flag(func, FUNC_USE_REPORTS); RNA_def_function_ui_description(func, "Remove a material from the current blendfile"); parm = RNA_def_pointer(func, "material", "Material", "", "Material to remove"); - RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); func = RNA_def_function(srna, "tag", "rna_Main_materials_tag"); parm = RNA_def_boolean(func, "value", 0, "Value", ""); @@ -852,7 +911,8 @@ void RNA_def_main_node_groups(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_flag(func, FUNC_USE_REPORTS); RNA_def_function_ui_description(func, "Remove a node tree from the current blendfile"); parm = RNA_def_pointer(func, "tree", "NodeTree", "", "Node tree to remove"); - RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); func = RNA_def_function(srna, "tag", "rna_Main_node_groups_tag"); parm = RNA_def_boolean(func, "value", 0, "Value", ""); @@ -886,7 +946,8 @@ void RNA_def_main_meshes(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_flag(func, FUNC_USE_REPORTS); RNA_def_function_ui_description(func, "Remove a mesh from the current blendfile"); parm = RNA_def_pointer(func, "mesh", "Mesh", "", "Mesh to remove"); - RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); func = RNA_def_function(srna, "tag", "rna_Main_meshes_tag"); parm = RNA_def_boolean(func, "value", 0, "Value", ""); @@ -922,7 +983,8 @@ void RNA_def_main_lamps(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_flag(func, FUNC_USE_REPORTS); RNA_def_function_ui_description(func, "Remove a lamp from the current blendfile"); parm = RNA_def_pointer(func, "lamp", "Lamp", "", "Lamp to remove"); - RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); func = RNA_def_function(srna, "tag", "rna_Main_lamps_tag"); parm = RNA_def_boolean(func, "value", 0, "Value", ""); @@ -1034,7 +1096,8 @@ void RNA_def_main_images(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_flag(func, FUNC_USE_REPORTS); RNA_def_function_ui_description(func, "Remove an image from the current blendfile"); parm = RNA_def_pointer(func, "image", "Image", "", "Image to remove"); - RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); func = RNA_def_function(srna, "tag", "rna_Main_images_tag"); parm = RNA_def_boolean(func, "value", 0, "Value", ""); @@ -1069,7 +1132,8 @@ void RNA_def_main_lattices(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_flag(func, FUNC_USE_REPORTS); RNA_def_function_ui_description(func, "Remove a lattice from the current blendfile"); parm = RNA_def_pointer(func, "lattice", "Lattice", "", "Lattice to remove"); - RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); func = RNA_def_function(srna, "tag", "rna_Main_lattices_tag"); parm = RNA_def_boolean(func, "value", 0, "Value", ""); @@ -1105,7 +1169,8 @@ void RNA_def_main_curves(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_flag(func, FUNC_USE_REPORTS); RNA_def_function_ui_description(func, "Remove a curve from the current blendfile"); parm = RNA_def_pointer(func, "curve", "Curve", "", "Curve to remove"); - RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); func = RNA_def_function(srna, "tag", "rna_Main_curves_tag"); parm = RNA_def_boolean(func, "value", 0, "Value", ""); @@ -1139,7 +1204,8 @@ void RNA_def_main_metaballs(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_flag(func, FUNC_USE_REPORTS); RNA_def_function_ui_description(func, "Remove a metaball from the current blendfile"); parm = RNA_def_pointer(func, "metaball", "MetaBall", "", "Metaball to remove"); - RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); func = RNA_def_function(srna, "tag", "rna_Main_metaballs_tag"); parm = RNA_def_boolean(func, "value", 0, "Value", ""); @@ -1174,7 +1240,8 @@ void RNA_def_main_fonts(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_flag(func, FUNC_USE_REPORTS); RNA_def_function_ui_description(func, "Remove a font from the current blendfile"); parm = RNA_def_pointer(func, "vfont", "VectorFont", "", "Font to remove"); - RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); func = RNA_def_function(srna, "tag", "rna_Main_fonts_tag"); parm = RNA_def_boolean(func, "value", 0, "Value", ""); @@ -1210,7 +1277,8 @@ void RNA_def_main_textures(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_flag(func, FUNC_USE_REPORTS); RNA_def_function_ui_description(func, "Remove a texture from the current blendfile"); parm = RNA_def_pointer(func, "texture", "Texture", "", "Texture to remove"); - RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); func = RNA_def_function(srna, "tag", "rna_Main_textures_tag"); parm = RNA_def_boolean(func, "value", 0, "Value", ""); @@ -1244,7 +1312,8 @@ void RNA_def_main_brushes(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_flag(func, FUNC_USE_REPORTS); RNA_def_function_ui_description(func, "Remove a brush from the current blendfile"); parm = RNA_def_pointer(func, "brush", "Brush", "", "Brush to remove"); - RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); func = RNA_def_function(srna, "tag", "rna_Main_brushes_tag"); parm = RNA_def_boolean(func, "value", 0, "Value", ""); @@ -1279,7 +1348,8 @@ void RNA_def_main_worlds(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_flag(func, FUNC_USE_REPORTS); RNA_def_function_ui_description(func, "Remove a world from the current blendfile"); parm = RNA_def_pointer(func, "world", "World", "", "World to remove"); - RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); func = RNA_def_function(srna, "tag", "rna_Main_worlds_tag"); parm = RNA_def_boolean(func, "value", 0, "Value", ""); @@ -1313,7 +1383,8 @@ void RNA_def_main_groups(BlenderRNA *brna, PropertyRNA *cprop) func = RNA_def_function(srna, "remove", "rna_Main_groups_remove"); RNA_def_function_ui_description(func, "Remove a group from the current blendfile"); parm = RNA_def_pointer(func, "group", "Group", "", "Group to remove"); - RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); func = RNA_def_function(srna, "tag", "rna_Main_groups_tag"); parm = RNA_def_boolean(func, "value", 0, "Value", ""); @@ -1348,7 +1419,8 @@ void RNA_def_main_speakers(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_flag(func, FUNC_USE_REPORTS); RNA_def_function_ui_description(func, "Remove a speaker from the current blendfile"); parm = RNA_def_pointer(func, "speaker", "Speaker", "", "Speaker to remove"); - RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); func = RNA_def_function(srna, "tag", "rna_Main_speakers_tag"); parm = RNA_def_boolean(func, "value", 0, "Value", ""); @@ -1382,7 +1454,8 @@ void RNA_def_main_texts(BlenderRNA *brna, PropertyRNA *cprop) func = RNA_def_function(srna, "remove", "rna_Main_texts_remove"); RNA_def_function_ui_description(func, "Remove a text from the current blendfile"); parm = RNA_def_pointer(func, "text", "Text", "", "Text to remove"); - RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); /* load func */ func = RNA_def_function(srna, "load", "rna_Main_texts_load"); @@ -1450,7 +1523,8 @@ void RNA_def_main_armatures(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_flag(func, FUNC_USE_REPORTS); RNA_def_function_ui_description(func, "Remove a armature from the current blendfile"); parm = RNA_def_pointer(func, "armature", "Armature", "", "Armature to remove"); - RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); func = RNA_def_function(srna, "tag", "rna_Main_armatures_tag"); parm = RNA_def_boolean(func, "value", 0, "Value", ""); @@ -1484,7 +1558,8 @@ void RNA_def_main_actions(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_flag(func, FUNC_USE_REPORTS); RNA_def_function_ui_description(func, "Remove a action from the current blendfile"); parm = RNA_def_pointer(func, "action", "Action", "", "Action to remove"); - RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); func = RNA_def_function(srna, "tag", "rna_Main_actions_tag"); parm = RNA_def_boolean(func, "value", 0, "Value", ""); @@ -1518,7 +1593,8 @@ void RNA_def_main_particles(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_flag(func, FUNC_USE_REPORTS); RNA_def_function_ui_description(func, "Remove a particle settings instance from the current blendfile"); parm = RNA_def_pointer(func, "particle", "ParticleSettings", "", "Particle Settings to remove"); - RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); func = RNA_def_function(srna, "tag", "rna_Main_particles_tag"); parm = RNA_def_boolean(func, "value", 0, "Value", ""); @@ -1557,7 +1633,8 @@ void RNA_def_main_gpencil(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_flag(func, FUNC_USE_REPORTS); RNA_def_function_ui_description(func, "Remove a grease pencil instance from the current blendfile"); parm = RNA_def_pointer(func, "grease_pencil", "GreasePencil", "", "Grease Pencil to remove"); - RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); prop = RNA_def_property(srna, "is_updated", PROP_BOOLEAN, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_EDITABLE); @@ -1582,7 +1659,8 @@ void RNA_def_main_movieclips(BlenderRNA *brna, PropertyRNA *cprop) func = RNA_def_function(srna, "remove", "rna_Main_movieclips_remove"); RNA_def_function_ui_description(func, "Remove a movie clip from the current blendfile."); parm = RNA_def_pointer(func, "clip", "MovieClip", "", "Movie clip to remove"); - RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); /* load func */ func = RNA_def_function(srna, "load", "rna_Main_movieclip_load"); @@ -1613,7 +1691,7 @@ void RNA_def_main_masks(BlenderRNA *brna, PropertyRNA *cprop) /* new func */ func = RNA_def_function(srna, "new", "rna_Main_mask_new"); RNA_def_function_ui_description(func, "Add a new mask with a given name to the main database"); - parm = RNA_def_string_file_path(func, "name", "", MAX_ID_NAME - 2, "Mask", "Name of new mask datablock"); + RNA_def_string_file_path(func, "name", "", MAX_ID_NAME - 2, "Mask", "Name of new mask datablock"); /* return type */ parm = RNA_def_pointer(func, "mask", "Mask", "", "New mask datablock"); RNA_def_function_return(func, parm); @@ -1622,7 +1700,8 @@ void RNA_def_main_masks(BlenderRNA *brna, PropertyRNA *cprop) func = RNA_def_function(srna, "remove", "rna_Main_masks_remove"); RNA_def_function_ui_description(func, "Remove a masks from the current blendfile."); parm = RNA_def_pointer(func, "mask", "Mask", "", "Mask to remove"); - RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); } void RNA_def_main_linestyles(BlenderRNA *brna, PropertyRNA *cprop) diff --git a/source/blender/makesrna/intern/rna_mask.c b/source/blender/makesrna/intern/rna_mask.c index d7243dc519f..56caa254a59 100644 --- a/source/blender/makesrna/intern/rna_mask.c +++ b/source/blender/makesrna/intern/rna_mask.c @@ -315,14 +315,16 @@ static MaskLayer *rna_Mask_layers_new(Mask *mask, const char *name) return masklay; } -static void rna_Mask_layers_remove(Mask *mask, ReportList *reports, MaskLayer *masklay) +static void rna_Mask_layers_remove(Mask *mask, ReportList *reports, PointerRNA *masklay_ptr) { + MaskLayer *masklay = masklay_ptr->data; if (BLI_findindex(&mask->masklayers, masklay) == -1) { BKE_reportf(reports, RPT_ERROR, "Mask layer '%s' not found in mask '%s'", masklay->name, mask->id.name + 2); return; } BKE_mask_layer_remove(mask, masklay); + RNA_POINTER_INVALIDATE(masklay_ptr); WM_main_add_notifier(NC_MASK | NA_EDITED, mask); } @@ -705,7 +707,9 @@ static void rna_def_masklayers(BlenderRNA *brna, PropertyRNA *cprop) func = RNA_def_function(srna, "remove", "rna_Mask_layers_remove"); RNA_def_function_flag(func, FUNC_USE_REPORTS); RNA_def_function_ui_description(func, "Remove layer from this mask"); - RNA_def_pointer(func, "layer", "MaskLayer", "", "Shape to be removed"); + parm = RNA_def_pointer(func, "layer", "MaskLayer", "", "Shape to be removed"); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); /* clear all layers */ func = RNA_def_function(srna, "clear", "rna_Mask_layers_clear"); diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c index 5e8dda7c065..9232ae098ea 100644 --- a/source/blender/makesrna/intern/rna_material.c +++ b/source/blender/makesrna/intern/rna_material.c @@ -1837,10 +1837,10 @@ void RNA_def_material(BlenderRNA *brna) "from other scene lighting"); RNA_def_property_update(prop, 0, "rna_Material_update"); - prop = RNA_def_property(srna, "use_light_group_local", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "shade_flag", MA_GROUP_LOCAL); - RNA_def_property_ui_text(prop, "Light Group Local", "When linked in, material uses local light group with the same name"); - RNA_def_property_update(prop, 0, "rna_Material_update"); + prop = RNA_def_property(srna, "use_light_group_local", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "shade_flag", MA_GROUP_LOCAL); + RNA_def_property_ui_text(prop, "Light Group Local", "When linked in, material uses local light group with the same name"); + RNA_def_property_update(prop, 0, "rna_Material_update"); prop = RNA_def_property(srna, "use_raytrace", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_TRACEBLE); diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index 5ddf2073f19..ec7f92374a7 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -2409,7 +2409,8 @@ static void rna_def_loop_colors(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_ui_description(func, "Remove a vertex color layer"); RNA_def_function_flag(func, FUNC_USE_REPORTS); parm = RNA_def_pointer(func, "layer", "Layer", "", "The layer to remove"); - RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); #endif prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_UNSIGNED); @@ -2586,7 +2587,8 @@ static void rna_def_uv_textures(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_ui_description(func, "Remove a vertex color layer"); RNA_def_function_flag(func, FUNC_USE_REPORTS); parm = RNA_def_pointer(func, "layer", "Layer", "", "The layer to remove"); - RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); #endif prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_UNSIGNED); diff --git a/source/blender/makesrna/intern/rna_mesh_api.c b/source/blender/makesrna/intern/rna_mesh_api.c index b63390c65ed..1e75569c841 100644 --- a/source/blender/makesrna/intern/rna_mesh_api.c +++ b/source/blender/makesrna/intern/rna_mesh_api.c @@ -78,7 +78,7 @@ void RNA_api_mesh(StructRNA *srna) RNA_def_function_flag(func, FUNC_USE_CONTEXT); func = RNA_def_function(srna, "unit_test_compare", "rna_Mesh_unit_test_compare"); - parm = RNA_def_pointer(func, "mesh", "Mesh", "", "Mesh to compare to"); + RNA_def_pointer(func, "mesh", "Mesh", "", "Mesh to compare to"); RNA_def_function_flag(func, FUNC_USE_CONTEXT); /* return value */ parm = RNA_def_string(func, "result", "nothing", 64, "Return value", "String description of result of comparison"); diff --git a/source/blender/makesrna/intern/rna_meta.c b/source/blender/makesrna/intern/rna_meta.c index fe2c29632f2..08eefc082bf 100644 --- a/source/blender/makesrna/intern/rna_meta.c +++ b/source/blender/makesrna/intern/rna_meta.c @@ -27,6 +27,7 @@ #include <stdlib.h> +#include "RNA_access.h" #include "RNA_define.h" #include "RNA_enum_types.h" @@ -126,19 +127,17 @@ static MetaElem *rna_MetaBall_elements_new(MetaBall *mb, int type) return ml; } -static void rna_MetaBall_elements_remove(MetaBall *mb, ReportList *reports, MetaElem *ml) +static void rna_MetaBall_elements_remove(MetaBall *mb, ReportList *reports, PointerRNA *ml_ptr) { - int found = 0; + MetaElem *ml = ml_ptr->data; - found = BLI_remlink_safe(&mb->elems, ml); - - if (!found) { + if (BLI_remlink_safe(&mb->elems, ml) == FALSE) { BKE_reportf(reports, RPT_ERROR, "Metaball '%s' does not contain spline given", mb->id.name + 2); return; } MEM_freeN(ml); - /* invalidate pointer!, no can do */ + RNA_POINTER_INVALIDATE(ml_ptr); /* cheating way for importers to avoid slow updates */ if (mb->id.us > 0) { @@ -254,7 +253,8 @@ static void rna_def_metaball_elements(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_ui_description(func, "Remove an element from the metaball"); RNA_def_function_flag(func, FUNC_USE_REPORTS); parm = RNA_def_pointer(func, "element", "MetaElement", "", "The element to remove"); - RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); func = RNA_def_function(srna, "clear", "rna_MetaBall_elements_clear"); RNA_def_function_ui_description(func, "Remove all elements from the metaball"); diff --git a/source/blender/makesrna/intern/rna_nla.c b/source/blender/makesrna/intern/rna_nla.c index 8378cb92e20..574f06e9107 100644 --- a/source/blender/makesrna/intern/rna_nla.c +++ b/source/blender/makesrna/intern/rna_nla.c @@ -27,6 +27,7 @@ #include <stdlib.h> +#include "RNA_access.h" #include "RNA_define.h" #include "rna_internal.h" @@ -345,16 +346,18 @@ static NlaStrip *rna_NlaStrip_new(NlaTrack *track, bContext *C, ReportList *repo return strip; } -static void rna_NlaStrip_remove(NlaTrack *track, bContext *C, ReportList *reports, NlaStrip *strip) +static void rna_NlaStrip_remove(NlaTrack *track, bContext *C, ReportList *reports, PointerRNA *strip_ptr) { + NlaStrip *strip = strip_ptr->data; if (BLI_findindex(&track->strips, strip) == -1) { BKE_reportf(reports, RPT_ERROR, "NLA strip '%s' not found in track '%s'", strip->name, track->name); return; } - else { - free_nlastrip(&track->strips, strip); - WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_REMOVED, NULL); - } + + free_nlastrip(&track->strips, strip); + RNA_POINTER_INVALIDATE(strip_ptr); + + WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_REMOVED, NULL); } /* Set the 'solo' setting for the given NLA-track, making sure that it is the only one @@ -639,7 +642,8 @@ static void rna_api_nlatrack_strips(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_flag(func, FUNC_USE_CONTEXT | FUNC_USE_REPORTS); RNA_def_function_ui_description(func, "Remove a NLA Strip"); parm = RNA_def_pointer(func, "strip", "NlaStrip", "", "NLA Strip to remove"); - RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); } static void rna_def_nlatrack(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 241ee8f9c9b..ece5c82f747 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -35,12 +35,16 @@ #include "rna_internal_types.h" #include "BLI_listbase.h" +#include "BLI_math.h" +#include "BLI_string.h" +#include "BLI_utildefines.h" #include "DNA_material_types.h" #include "DNA_mesh_types.h" #include "DNA_node_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" +#include "DNA_text_types.h" #include "DNA_texture_types.h" #include "BKE_animsys.h" @@ -48,9 +52,9 @@ #include "BKE_node.h" #include "BKE_image.h" #include "BKE_texture.h" +#include "BKE_idprop.h" -#include "BLI_math.h" -#include "BLI_utildefines.h" +#include "IMB_imbuf.h" #include "WM_types.h" @@ -206,6 +210,8 @@ EnumPropertyItem prop_wave_items[] = { #include "BLI_linklist.h" +#include "BKE_global.h" + #include "ED_node.h" #include "RE_pipeline.h" @@ -749,20 +755,20 @@ static bNode *rna_NodeTree_node_texture_new(bNodeTree *ntree, bContext *C, Repor return node; } -static void rna_NodeTree_node_remove(bNodeTree *ntree, ReportList *reports, bNode *node) +static void rna_NodeTree_node_remove(bNodeTree *ntree, ReportList *reports, PointerRNA *node_ptr) { + bNode *node = node_ptr->data; if (BLI_findindex(&ntree->nodes, node) == -1) { BKE_reportf(reports, RPT_ERROR, "Unable to locate node '%s' in node tree", node->name); + return; } - else { - if (node->id) - id_us_min(node->id); - nodeFreeNode(ntree, node); - ntreeUpdateTree(ntree); /* update group node socket links*/ + id_us_min(node->id); + nodeFreeNode(ntree, node); + RNA_POINTER_INVALIDATE(node_ptr); - WM_main_add_notifier(NC_NODE | NA_EDITED, ntree); - } + ntreeUpdateTree(ntree); /* update group node socket links */ + WM_main_add_notifier(NC_NODE | NA_EDITED, ntree); } static void rna_NodeTree_node_clear(bNodeTree *ntree) @@ -820,17 +826,19 @@ static bNodeLink *rna_NodeTree_link_new(bNodeTree *ntree, ReportList *reports, return ret; } -static void rna_NodeTree_link_remove(bNodeTree *ntree, ReportList *reports, bNodeLink *link) +static void rna_NodeTree_link_remove(bNodeTree *ntree, ReportList *reports, PointerRNA *link_ptr) { + bNodeLink *link = link_ptr->data; if (BLI_findindex(&ntree->links, link) == -1) { BKE_report(reports, RPT_ERROR, "Unable to locate link in node tree"); + return; } - else { - nodeRemLink(ntree, link); - ntreeUpdateTree(ntree); - WM_main_add_notifier(NC_NODE | NA_EDITED, ntree); - } + nodeRemLink(ntree, link); + RNA_POINTER_INVALIDATE(link_ptr); + + ntreeUpdateTree(ntree); + WM_main_add_notifier(NC_NODE | NA_EDITED, ntree); } static void rna_NodeTree_link_clear(bNodeTree *ntree) @@ -993,6 +1001,129 @@ static void rna_NodeOutputFileSlotLayer_name_set(PointerRNA *ptr, const char *va } } +static bNodeSocket *rna_ShaderNodeScript_find_socket(bNode *node, const char *name, int is_output) +{ + bNodeSocket *sock; + + if (is_output) { + for (sock = node->outputs.first; sock; sock = sock->next) { + if (strcmp(sock->name, name) == 0) { + return sock; + } + } + } + else { + for (sock = node->inputs.first; sock; sock = sock->next) { + if (strcmp(sock->name, name) == 0) { + return sock; + } + } + } + + return NULL; +} + +static void rna_ShaderNodeScript_remove_socket(ID *id, bNode *node, bNodeSocket *sock) +{ + bNodeTree *ntree = (bNodeTree *)id; + + nodeRemoveSocket(ntree, node, sock); + + ED_node_generic_update(G.main, ntree, node); +} + +static bNodeSocket *rna_ShaderNodeScript_add_socket(ID *id, bNode *node, const char *name, int type, int is_output) +{ + bNodeTree *ntree = (bNodeTree *)id; + bNodeSocket *sock; + + /* replace existing socket with the same name, to keep it unique */ + sock = rna_ShaderNodeScript_find_socket(node, name, is_output); + if (sock) + nodeRemoveSocket(ntree, node, sock); + sock = nodeAddSocket(ntree, node, (is_output ? SOCK_OUT : SOCK_IN), name, type); + + ED_node_generic_update(G.main, ntree, node); + + return sock; +} + +static void rna_ShaderNodeScript_mode_set(PointerRNA *ptr, int value) +{ + bNode *node = (bNode *)ptr->data; + NodeShaderScript *nss = node->storage; + + if (nss->mode != value) { + nss->mode = value; + nss->filepath[0] = '\0'; + nss->flag &= ~NODE_SCRIPT_AUTO_UPDATE; + + /* replace text datablock by filepath */ + if (node->id) { + Text *text = (Text*)node->id; + + if (value == NODE_SCRIPT_EXTERNAL && text->name) { + BLI_strncpy(nss->filepath, text->name, sizeof(nss->filepath)); + BLI_path_rel(nss->filepath, G.main->name); + } + + id_us_min(node->id); + node->id = NULL; + } + + /* remove any bytecode */ + if (nss->bytecode) { + MEM_freeN(nss->bytecode); + nss->bytecode = NULL; + } + + nss->bytecode_hash[0] = '\0'; + } +} + +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: ""); +} + +static int rna_ShaderNodeScript_bytecode_length(PointerRNA *ptr) +{ + bNode *node = (bNode *)ptr->data; + NodeShaderScript *nss = node->storage; + + return (nss->bytecode) ? strlen(nss->bytecode) : 0; +} + +static void rna_ShaderNodeScript_bytecode_set(PointerRNA *ptr, const char *value) +{ + bNode *node = (bNode *)ptr->data; + NodeShaderScript *nss = node->storage; + + if (nss->bytecode) + MEM_freeN(nss->bytecode); + + if (value && value[0]) + nss->bytecode = BLI_strdup(value); + else + nss->bytecode = NULL; +} + +static IDProperty *rna_ShaderNodeScript_idprops(PointerRNA *ptr, int create) +{ + bNode *node = (bNode *)ptr->data; + NodeShaderScript *nss = node->storage; + + if (create && !nss->prop) { + IDPropertyTemplate val = {0}; + nss->prop = IDP_New(IDP_GROUP, &val, "RNA_ShaderNodeScript ID properties"); + } + + return nss->prop; +} + #else static EnumPropertyItem prop_image_layer_items[] = { @@ -1033,6 +1164,12 @@ static EnumPropertyItem node_glossy_items[] = { {0, NULL, 0, NULL, NULL} }; +static EnumPropertyItem node_script_mode_items[] = { + {NODE_SCRIPT_INTERNAL, "INTERNAL", 0, "Internal", "Use internal text datablock"}, + {NODE_SCRIPT_EXTERNAL, "EXTERNAL", 0, "External", "Use external .osl or oso file"}, + {0, NULL, 0, NULL, NULL} +}; + #define MaxNodes 50000 enum @@ -1705,6 +1842,76 @@ static void def_glossy(StructRNA *srna) RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); } +static void def_sh_script(StructRNA *srna) +{ + FunctionRNA *func; + PropertyRNA *prop, *parm; + + prop = RNA_def_property(srna, "script", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "id"); + RNA_def_property_struct_type(prop, "Text"); + RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT); + RNA_def_property_ui_text(prop, "Script", "Internal shader script to define the shader"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); + + RNA_def_struct_sdna_from(srna, "NodeShaderScript", "storage"); + RNA_def_struct_idprops_func(srna, "rna_ShaderNodeScript_idprops"); + + prop = RNA_def_property(srna, "filepath", PROP_STRING, PROP_FILEPATH); + RNA_def_property_ui_text(prop, "File Path", "Shader script path"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); + + prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_funcs(prop, NULL, "rna_ShaderNodeScript_mode_set", NULL); + RNA_def_property_enum_items(prop, node_script_mode_items); + RNA_def_property_ui_text(prop, "Script Source", ""); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); + + prop = RNA_def_property(srna, "use_auto_update", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", NODE_SCRIPT_AUTO_UPDATE); + RNA_def_property_ui_text(prop, "Auto Update", "Automatically updates the shader when the .osl file changes - external scripts only"); + + prop = RNA_def_property(srna, "bytecode", PROP_STRING, PROP_NONE); + RNA_def_property_string_funcs(prop, "rna_ShaderNodeScript_bytecode_get", + "rna_ShaderNodeScript_bytecode_length", "rna_ShaderNodeScript_bytecode_set"); + RNA_def_property_ui_text(prop, "Bytecode", "Compile bytecode for shader script node"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); + + prop = RNA_def_property(srna, "bytecode_hash", PROP_STRING, PROP_NONE); + RNA_def_property_ui_text(prop, "Bytecode Hash", "Hash of compile bytecode, for quick equality checking"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); + + /* needs to be reset to avoid bad pointer type in API functions below */ + RNA_def_struct_sdna_from(srna, "bNode", NULL); + + /* API functions */ + + func = RNA_def_function(srna, "find_socket", "rna_ShaderNodeScript_find_socket"); + RNA_def_function_ui_description(func, "Find a socket by name"); + parm = RNA_def_string(func, "name", "", 0, "Socket name", ""); + RNA_def_property_flag(parm, PROP_REQUIRED); + /*parm =*/ RNA_def_boolean(func, "is_output", FALSE, "Output", "Whether the socket is an output"); + parm = RNA_def_pointer(func, "result", "NodeSocket", "", ""); + RNA_def_function_return(func, parm); + + func = RNA_def_function(srna, "add_socket", "rna_ShaderNodeScript_add_socket"); + RNA_def_function_ui_description(func, "Add a socket socket"); + RNA_def_function_flag(func, FUNC_USE_SELF_ID); + parm = RNA_def_string(func, "name", "", 0, "Name", ""); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm = RNA_def_enum(func, "type", node_socket_type_items, SOCK_FLOAT, "Type", ""); + RNA_def_property_flag(parm, PROP_REQUIRED); + /*parm =*/ RNA_def_boolean(func, "is_output", FALSE, "Output", "Whether the socket is an output"); + parm = RNA_def_pointer(func, "result", "NodeSocket", "", ""); + RNA_def_function_return(func, parm); + + func = RNA_def_function(srna, "remove_socket", "rna_ShaderNodeScript_remove_socket"); + RNA_def_function_ui_description(func, "Remove a socket socket"); + RNA_def_function_flag(func, FUNC_USE_SELF_ID); + parm = RNA_def_pointer(func, "sock", "NodeSocket", "Socket", ""); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); +} + /* -- Compositor Nodes ------------------------------------------------------ */ static void def_cmp_alpha_over(StructRNA *srna) @@ -4001,7 +4208,8 @@ static void rna_def_nodetree_link_api(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_ui_description(func, "remove a node link from the node tree"); RNA_def_function_flag(func, FUNC_USE_REPORTS); parm = RNA_def_pointer(func, "link", "NodeLink", "", "The node link to remove"); - RNA_def_property_flag(parm, PROP_REQUIRED); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); func = RNA_def_function(srna, "clear", "rna_NodeTree_link_clear"); RNA_def_function_ui_description(func, "remove all node links from the node tree"); @@ -4045,7 +4253,8 @@ static void rna_def_composite_nodetree_api(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_ui_description(func, "Remove a node from this node tree"); RNA_def_function_flag(func, FUNC_USE_REPORTS); parm = RNA_def_pointer(func, "node", "Node", "", "The node to remove"); - RNA_def_property_flag(parm, PROP_REQUIRED); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); func = RNA_def_function(srna, "clear", "rna_NodeTree_node_clear"); RNA_def_function_ui_description(func, "Remove all nodes from this node tree"); @@ -4078,7 +4287,8 @@ static void rna_def_shader_nodetree_api(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_ui_description(func, "Remove a node from this node tree"); RNA_def_function_flag(func, FUNC_USE_REPORTS); parm = RNA_def_pointer(func, "node", "Node", "", "The node to remove"); - RNA_def_property_flag(parm, PROP_REQUIRED); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); func = RNA_def_function(srna, "clear", "rna_NodeTree_node_clear"); RNA_def_function_ui_description(func, "Remove all nodes from this node tree"); @@ -4111,7 +4321,8 @@ static void rna_def_texture_nodetree_api(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_ui_description(func, "Remove a node from this node tree"); RNA_def_function_flag(func, FUNC_USE_REPORTS); parm = RNA_def_pointer(func, "node", "Node", "", "The node to remove"); - RNA_def_property_flag(parm, PROP_REQUIRED); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); func = RNA_def_function(srna, "clear", "rna_NodeTree_node_clear"); RNA_def_function_ui_description(func, "Remove all nodes from this node tree"); diff --git a/source/blender/makesrna/intern/rna_nodetree_types.h b/source/blender/makesrna/intern/rna_nodetree_types.h index 6d97e959112..c45c9b71442 100644 --- a/source/blender/makesrna/intern/rna_nodetree_types.h +++ b/source/blender/makesrna/intern/rna_nodetree_types.h @@ -82,7 +82,8 @@ DefNode( ShaderNode, SH_NODE_LIGHT_PATH, 0, "LI DefNode( ShaderNode, SH_NODE_LIGHT_FALLOFF, 0, "LIGHT_FALLOFF", LightFalloff, "Light Falloff", "" ) DefNode( ShaderNode, SH_NODE_OBJECT_INFO, 0, "OBJECT_INFO", ObjectInfo, "Object Info", "" ) DefNode( ShaderNode, SH_NODE_PARTICLE_INFO, 0, "PARTICLE_INFO", ParticleInfo, "Particle Info", "" ) -DefNode( ShaderNode, SH_NODE_BUMP, 0, "BUMP", BumpNode, "Bump", "" ) +DefNode( ShaderNode, SH_NODE_BUMP, 0, "BUMP", BumpNode, "Bump", "" ) +DefNode( ShaderNode, SH_NODE_SCRIPT, def_sh_script, "SCRIPT", Script, "Script", "" ) DefNode( ShaderNode, SH_NODE_TEX_IMAGE, def_sh_tex_image, "TEX_IMAGE", TexImage, "Image Texture", "" ) DefNode( ShaderNode, SH_NODE_TEX_ENVIRONMENT, def_sh_tex_environment, "TEX_ENVIRONMENT", TexEnvironment, "Environment Texture","" ) DefNode( ShaderNode, SH_NODE_TEX_SKY, def_sh_tex_sky, "TEX_SKY", TexSky, "Sky Texture", "" ) diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index 0c1ec0b02f9..10f361ef1bd 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -851,11 +851,11 @@ static void rna_MaterialSlot_link_set(PointerRNA *ptr, int value) if (value) { ob->matbits[index] = 1; - /* ob->colbits |= (1<<index); */ /* DEPRECATED */ + /* ob->colbits |= (1 << index); */ /* DEPRECATED */ } else { ob->matbits[index] = 0; - /* ob->colbits &= ~(1<<index); */ /* DEPRECATED */ + /* ob->colbits &= ~(1 << index); */ /* DEPRECATED */ } } @@ -1036,8 +1036,8 @@ static unsigned int rna_Object_layer_validate__internal(const int *values, unsig return 0; for (i = 0; i < 20; i++) { - if (values[i]) lay |= (1 << i); - else lay &= ~(1 << i); + if (values[i]) lay |= (1 << i); + else lay &= ~(1 << i); } return lay; @@ -1072,8 +1072,9 @@ static void rna_GameObjectSettings_state_get(PointerRNA *ptr, int *values) int all_states = (ob->scaflag & OB_ALLSTATE ? 1 : 0); memset(values, 0, sizeof(int) * OB_MAX_STATES); - for (i = 0; i < OB_MAX_STATES; i++) + for (i = 0; i < OB_MAX_STATES; i++) { values[i] = (ob->state & (1 << i)) | all_states; + } } static void rna_GameObjectSettings_state_set(PointerRNA *ptr, const int *values) @@ -1111,6 +1112,65 @@ static void rna_GameObjectSettings_used_state_get(PointerRNA *ptr, int *values) } } +static void rna_GameObjectSettings_col_group_get(PointerRNA *ptr, int *values) +{ + Object *ob = (Object*)ptr->data; + int i; + + for (i = 0; i < OB_MAX_COL_MASKS; i++) { + values[i] = (ob->col_group & (1 << i)); + } +} + +static void rna_GameObjectSettings_col_group_set(PointerRNA *ptr, const int *values) +{ + Object *ob = (Object*)ptr->data; + int i, tot = 0; + + /* ensure we always have some group selected */ + for (i = 0; i < OB_MAX_COL_MASKS; i++) + if (values[i]) + tot++; + + if (tot == 0) + return; + + for (i = 0; i < OB_MAX_COL_MASKS; i++) { + if (values[i]) ob->col_group |= (1 << i); + else ob->col_group &= ~(1 << i); + } +} + +static void rna_GameObjectSettings_col_mask_get(PointerRNA *ptr, int *values) +{ + Object *ob = (Object*)ptr->data; + int i; + + for (i = 0; i < OB_MAX_COL_MASKS; i++) { + values[i] = (ob->col_mask & (1 << i)); + } +} + +static void rna_GameObjectSettings_col_mask_set(PointerRNA *ptr, const int *values) +{ + Object *ob = (Object*)ptr->data; + int i, tot = 0; + + /* ensure we always have some mask selected */ + for (i = 0; i < OB_MAX_COL_MASKS; i++) + if (values[i]) + tot++; + + if (tot == 0) + return; + + for (i = 0; i < OB_MAX_COL_MASKS; i++) { + if (values[i]) ob->col_mask |= (1 << i); + else ob->col_mask &= ~(1 << i); + } +} + + static void rna_Object_active_shape_key_index_range(PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax) { Object *ob = (Object *)ptr->id.data; @@ -1199,14 +1259,17 @@ static bConstraint *rna_Object_constraints_new(Object *object, int type) return add_ob_constraint(object, NULL, type); } -static void rna_Object_constraints_remove(Object *object, ReportList *reports, bConstraint *con) +static void rna_Object_constraints_remove(Object *object, ReportList *reports, PointerRNA *con_ptr) { + bConstraint *con = con_ptr->data; if (BLI_findindex(&object->constraints, con) == -1) { BKE_reportf(reports, RPT_ERROR, "Constraint '%s' not found in object '%s'", con->name, object->id.name + 2); return; } remove_constraint(&object->constraints, con); + RNA_POINTER_INVALIDATE(con_ptr); + ED_object_constraint_update(object); ED_object_constraint_set_active(object, NULL); WM_main_add_notifier(NC_OBJECT | ND_CONSTRAINT | NA_REMOVED, object); @@ -1228,9 +1291,15 @@ static ModifierData *rna_Object_modifier_new(Object *object, bContext *C, Report return ED_object_modifier_add(reports, CTX_data_main(C), CTX_data_scene(C), object, name, type); } -static void rna_Object_modifier_remove(Object *object, bContext *C, ReportList *reports, ModifierData *md) +static void rna_Object_modifier_remove(Object *object, bContext *C, ReportList *reports, PointerRNA *md_ptr) { - ED_object_modifier_remove(reports, CTX_data_main(C), CTX_data_scene(C), object, md); + ModifierData *md = md_ptr->data; + if (ED_object_modifier_remove(reports, CTX_data_main(C), CTX_data_scene(C), object, md) == FALSE) { + /* error is already set */ + return; + } + + RNA_POINTER_INVALIDATE(md_ptr); WM_main_add_notifier(NC_OBJECT | ND_MODIFIER | NA_REMOVED, object); } @@ -1264,9 +1333,16 @@ static bDeformGroup *rna_Object_vgroup_new(Object *ob, const char *name) return defgroup; } -static void rna_Object_vgroup_remove(Object *ob, bDeformGroup *defgroup) +static void rna_Object_vgroup_remove(Object *ob, ReportList *reports, PointerRNA *defgroup_ptr) { + bDeformGroup *defgroup = defgroup_ptr->data; + if (BLI_findindex(&ob->defbase, defgroup) == -1) { + BKE_reportf(reports, RPT_ERROR, "DeformGroup '%s' not in object '%s'", defgroup->name, ob->id.name + 2); + return; + } + ED_vgroup_delete(ob, defgroup); + RNA_POINTER_INVALIDATE(defgroup_ptr); WM_main_add_notifier(NC_OBJECT | ND_DRAW, ob); } @@ -1578,6 +1654,17 @@ static void rna_def_object_game_settings(BlenderRNA *brna) RNA_def_property_range(prop, 0.0, 1000.0); RNA_def_property_ui_text(prop, "Fall Speed Max", "Maximum speed at which the character will fall"); + prop = RNA_def_property(srna, "collision_group", PROP_BOOLEAN, PROP_LAYER_MEMBER); + RNA_def_property_boolean_sdna(prop, NULL, "col_group", 1); + RNA_def_property_array(prop, OB_MAX_COL_MASKS); + RNA_def_property_ui_text(prop, "Collision Group", "The collision group of the object"); + RNA_def_property_boolean_funcs(prop, "rna_GameObjectSettings_col_group_get", "rna_GameObjectSettings_col_group_set"); + + prop = RNA_def_property(srna, "collision_mask", PROP_BOOLEAN, PROP_LAYER_MEMBER); + RNA_def_property_boolean_sdna(prop, NULL, "col_mask", 1); + RNA_def_property_array(prop, OB_MAX_COL_MASKS); + RNA_def_property_ui_text(prop, "Collision Mask", "The groups this object can collide with"); + RNA_def_property_boolean_funcs(prop, "rna_GameObjectSettings_col_mask_get", "rna_GameObjectSettings_col_mask_set"); /* lock position */ prop = RNA_def_property(srna, "lock_location_x", PROP_BOOLEAN, PROP_NONE); @@ -1745,7 +1832,8 @@ static void rna_def_object_constraints(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_flag(func, FUNC_USE_REPORTS); /* constraint to remove */ parm = RNA_def_pointer(func, "constraint", "Constraint", "", "Removed constraint"); - RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); func = RNA_def_function(srna, "clear", "rna_Object_constraints_clear"); RNA_def_function_ui_description(func, "Remove all constraint from this object"); @@ -1796,7 +1884,8 @@ static void rna_def_object_modifiers(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_ui_description(func, "Remove an existing modifier from the object"); /* modifier to remove */ parm = RNA_def_pointer(func, "modifier", "Modifier", "", "Modifier to remove"); - RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); /* clear all modifiers */ func = RNA_def_function(srna, "clear", "rna_Object_modifier_clear"); @@ -1874,9 +1963,11 @@ static void rna_def_object_vertex_groups(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_return(func, parm); func = RNA_def_function(srna, "remove", "rna_Object_vgroup_remove"); + RNA_def_function_flag(func, FUNC_USE_REPORTS); RNA_def_function_ui_description(func, "Delete vertex group from object"); parm = RNA_def_pointer(func, "group", "VertexGroup", "", "Vertex group to remove"); - RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); func = RNA_def_function(srna, "clear", "rna_Object_vgroup_clear"); RNA_def_function_ui_description(func, "Delete all vertex groups from object"); diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c index d1640a51ded..87fc3be28a2 100644 --- a/source/blender/makesrna/intern/rna_object_api.c +++ b/source/blender/makesrna/intern/rna_object_api.c @@ -613,7 +613,7 @@ void RNA_api_object(StructRNA *srna) "objects real matrix and layers"); parm = RNA_def_pointer(func, "scene", "Scene", "", "Scene within which to evaluate duplis"); RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); - parm = RNA_def_enum(func, "settings", mesh_type_items, 0, "", "Generate texture coordinates for rendering"); + RNA_def_enum(func, "settings", mesh_type_items, 0, "", "Generate texture coordinates for rendering"); RNA_def_function_flag(func, FUNC_USE_REPORTS); func = RNA_def_function(srna, "dupli_list_clear", "rna_Object_free_duplilist"); diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c index df278e7cf16..c29537378dd 100644 --- a/source/blender/makesrna/intern/rna_pose.c +++ b/source/blender/makesrna/intern/rna_pose.c @@ -497,24 +497,28 @@ static bConstraint *rna_PoseChannel_constraints_new(bPoseChannel *pchan, int typ return add_pose_constraint(NULL, pchan, NULL, type); } -static void rna_PoseChannel_constraints_remove(ID *id, bPoseChannel *pchan, ReportList *reports, bConstraint *con) +static void rna_PoseChannel_constraints_remove(ID *id, bPoseChannel *pchan, ReportList *reports, PointerRNA *con_ptr) { + bConstraint *con = con_ptr->data; + const short is_ik = ELEM(con->type, CONSTRAINT_TYPE_KINEMATIC, CONSTRAINT_TYPE_SPLINEIK); + Object *ob = (Object *)id; + if (BLI_findindex(&pchan->constraints, con) == -1) { BKE_reportf(reports, RPT_ERROR, "Constraint '%s' not found in pose bone '%s'", con->name, pchan->name); return; } - else { - Object *ob = (Object *)id; - const short is_ik = ELEM(con->type, CONSTRAINT_TYPE_KINEMATIC, CONSTRAINT_TYPE_SPLINEIK); - remove_constraint(&pchan->constraints, con); - ED_object_constraint_update(ob); - constraints_set_active(&pchan->constraints, NULL); - WM_main_add_notifier(NC_OBJECT | ND_CONSTRAINT | NA_REMOVED, id); + remove_constraint(&pchan->constraints, con); + RNA_POINTER_INVALIDATE(con_ptr); - if (is_ik) { - BIK_clear_data(ob->pose); - } + ED_object_constraint_update(ob); + + constraints_set_active(&pchan->constraints, NULL); /* XXX, is this really needed? - Campbell */ + + WM_main_add_notifier(NC_OBJECT | ND_CONSTRAINT | NA_REMOVED, id); + + if (is_ik) { + BIK_clear_data(ob->pose); } } @@ -727,7 +731,8 @@ static void rna_def_pose_channel_constraints(BlenderRNA *brna, PropertyRNA *cpro RNA_def_function_flag(func, FUNC_USE_REPORTS | FUNC_USE_SELF_ID); /* ID needed for refresh */ /* constraint to remove */ parm = RNA_def_pointer(func, "constraint", "Constraint", "", "Removed constraint"); - RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); } static void rna_def_pose_channel(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_render.c b/source/blender/makesrna/intern/rna_render.c index 4b4018433b3..56497e96c67 100644 --- a/source/blender/makesrna/intern/rna_render.c +++ b/source/blender/makesrna/intern/rna_render.c @@ -129,6 +129,24 @@ static void engine_view_draw(RenderEngine *engine, const struct bContext *contex RNA_parameter_list_free(&list); } +static void engine_update_script_node(RenderEngine *engine, struct bNodeTree *ntree, struct bNode *node) +{ + extern FunctionRNA rna_RenderEngine_update_script_node_func; + PointerRNA ptr, nodeptr; + ParameterList list; + FunctionRNA *func; + + RNA_pointer_create(NULL, engine->type->ext.srna, engine, &ptr); + RNA_pointer_create((ID*)ntree, &RNA_Node, node, &nodeptr); + func = &rna_RenderEngine_update_script_node_func; + + RNA_parameter_list_create(&list, &ptr, func); + RNA_parameter_set_lookup(&list, "node", &nodeptr); + engine->type->ext.call(NULL, &ptr, func, &list); + + RNA_parameter_list_free(&list); +} + /* RenderEngine registration */ static void rna_RenderEngine_unregister(Main *UNUSED(bmain), StructRNA *type) @@ -149,7 +167,7 @@ static StructRNA *rna_RenderEngine_register(Main *bmain, ReportList *reports, vo RenderEngineType *et, dummyet = {NULL}; RenderEngine dummyengine = {NULL}; PointerRNA dummyptr; - int have_function[4]; + int have_function[5]; /* setup dummy engine & engine type to store static properties in */ dummyengine.type = &dummyet; @@ -188,6 +206,7 @@ static StructRNA *rna_RenderEngine_register(Main *bmain, ReportList *reports, vo et->render = (have_function[1]) ? engine_render : NULL; et->view_update = (have_function[2]) ? engine_view_update : NULL; et->view_draw = (have_function[3]) ? engine_view_draw : NULL; + et->update_script_node = (have_function[4]) ? engine_update_script_node : NULL; BLI_addtail(&R_engines, et); @@ -300,6 +319,13 @@ static void rna_def_render_engine(BlenderRNA *brna) RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL); RNA_def_pointer(func, "context", "Context", "", ""); + /* shader script callbacks */ + func = RNA_def_function(srna, "update_script_node", NULL); + RNA_def_function_ui_description(func, "Compile shader script node"); + RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL | FUNC_ALLOW_WRITE); + prop = RNA_def_pointer(func, "node", "Node", "", ""); + RNA_def_property_flag(prop, PROP_RNAPTR); + /* tag for redraw */ RNA_def_function(srna, "tag_redraw", "engine_tag_redraw"); RNA_def_function_ui_description(func, "Request redraw for viewport rendering"); @@ -328,7 +354,7 @@ static void rna_def_render_engine(BlenderRNA *brna) func = RNA_def_function(srna, "end_result", "RE_engine_end_result"); prop = RNA_def_pointer(func, "result", "RenderResult", "Result", ""); RNA_def_property_flag(prop, PROP_REQUIRED); - prop = RNA_def_boolean(func, "cancel", 0, "Cancel", "Don't merge back results"); + RNA_def_boolean(func, "cancel", 0, "Cancel", "Don't merge back results"); func = RNA_def_function(srna, "test_break", "RE_engine_test_break"); prop = RNA_def_boolean(func, "do_break", 0, "Break", ""); diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index b71aa507591..42fb712786c 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -1036,17 +1036,20 @@ static SceneRenderLayer *rna_RenderLayer_new(ID *id, RenderData *UNUSED(rd), con } static void rna_RenderLayer_remove(ID *id, RenderData *UNUSED(rd), Main *bmain, ReportList *reports, - SceneRenderLayer *srl) + PointerRNA *srl_ptr) { + SceneRenderLayer *srl = srl_ptr->data; Scene *scene = (Scene *)id; if (!BKE_scene_remove_render_layer(bmain, scene, srl)) { BKE_reportf(reports, RPT_ERROR, "Render layer '%s' could not be removed from scene '%s'", srl->name, scene->id.name + 2); + return; } - else { - WM_main_add_notifier(NC_SCENE | ND_RENDER_OPTIONS, NULL); - } + + RNA_POINTER_INVALIDATE(srl_ptr); + + WM_main_add_notifier(NC_SCENE | ND_RENDER_OPTIONS, NULL); } static void rna_RenderSettings_engine_set(PointerRNA *ptr, int value) @@ -1336,15 +1339,16 @@ static TimeMarker *rna_TimeLine_add(Scene *scene, const char name[]) return marker; } -static void rna_TimeLine_remove(Scene *scene, ReportList *reports, TimeMarker *marker) +static void rna_TimeLine_remove(Scene *scene, ReportList *reports, PointerRNA *marker_ptr) { - if (!BLI_remlink_safe(&scene->markers, marker)) { + TimeMarker *marker = marker_ptr->data; + if (BLI_remlink_safe(&scene->markers, marker) == FALSE) { BKE_reportf(reports, RPT_ERROR, "Timeline marker '%s' not found in scene '%s'", marker->name, scene->id.name + 2); return; } - /* XXX, invalidates PyObject */ MEM_freeN(marker); + RNA_POINTER_INVALIDATE(marker_ptr); WM_main_add_notifier(NC_SCENE | ND_MARKERS, NULL); WM_main_add_notifier(NC_ANIMATION | ND_MARKERS, NULL); @@ -3249,7 +3253,8 @@ static void rna_def_render_layers(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_ui_description(func, "Remove a render layer"); RNA_def_function_flag(func, FUNC_USE_MAIN | FUNC_USE_REPORTS | FUNC_USE_SELF_ID); parm = RNA_def_pointer(func, "layer", "SceneRenderLayer", "", "Timeline marker to remove"); - RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); } /* use for render output and image save operator, @@ -4581,7 +4586,8 @@ static void rna_def_timeline_markers(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_ui_description(func, "Remove a timeline marker"); RNA_def_function_flag(func, FUNC_USE_REPORTS); parm = RNA_def_pointer(func, "marker", "TimelineMarker", "", "Timeline marker to remove"); - RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); func = RNA_def_function(srna, "clear", "rna_TimeLine_clear"); RNA_def_function_ui_description(func, "Remove all timeline markers"); diff --git a/source/blender/makesrna/intern/rna_scene_api.c b/source/blender/makesrna/intern/rna_scene_api.c index 10efc7a94a7..63253153699 100644 --- a/source/blender/makesrna/intern/rna_scene_api.c +++ b/source/blender/makesrna/intern/rna_scene_api.c @@ -89,29 +89,29 @@ static void rna_SceneRender_get_frame_path(RenderData *rd, int frame, char *name #include "../../collada/collada.h" static void rna_Scene_collada_export( - Scene *scene, - const char *filepath, - int apply_modifiers, - int export_mesh_type, - - int selected, - int include_children, - int include_armatures, - int deform_bones_only, - - int active_uv_only, - int include_uv_textures, - int include_material_textures, - int use_texture_copies, - - int use_object_instantiation, - int sort_by_name, - int second_life) + Scene *scene, + const char *filepath, + int apply_modifiers, + int export_mesh_type, + + int selected, + int include_children, + int include_armatures, + int deform_bones_only, + + int active_uv_only, + int include_uv_textures, + int include_material_textures, + int use_texture_copies, + + int use_object_instantiation, + int sort_by_name, + int second_life) { - collada_export(scene, filepath, apply_modifiers, export_mesh_type, selected, + collada_export(scene, filepath, apply_modifiers, export_mesh_type, selected, include_children, include_armatures, deform_bones_only, - active_uv_only, include_uv_textures, include_material_textures, - use_texture_copies, use_object_instantiation, sort_by_name, second_life); + active_uv_only, include_uv_textures, include_material_textures, + use_texture_copies, use_object_instantiation, sort_by_name, second_life); } #endif diff --git a/source/blender/makesrna/intern/rna_sequencer.c b/source/blender/makesrna/intern/rna_sequencer.c index d8ca1aea5dd..054d0cc82c6 100644 --- a/source/blender/makesrna/intern/rna_sequencer.c +++ b/source/blender/makesrna/intern/rna_sequencer.c @@ -966,18 +966,20 @@ static SequenceModifierData *rna_Sequence_modifier_new(Sequence *seq, bContext * } } -static void rna_Sequence_modifier_remove(Sequence *seq, bContext *C, ReportList *reports, SequenceModifierData *smd) +static void rna_Sequence_modifier_remove(Sequence *seq, bContext *C, ReportList *reports, PointerRNA *smd_ptr) { + SequenceModifierData *smd = smd_ptr->data; Scene *scene = CTX_data_scene(C); - if (BKE_sequence_modifier_remove(seq, smd)) { - BKE_sequence_invalidate_cache_for_modifier(scene, seq); - - WM_main_add_notifier(NC_SCENE | ND_SEQUENCER, NULL); - } - else { + if (BKE_sequence_modifier_remove(seq, smd) == FALSE) { BKE_report(reports, RPT_ERROR, "Modifier was not found in the stack"); + return; } + + RNA_POINTER_INVALIDATE(smd_ptr); + BKE_sequence_invalidate_cache_for_modifier(scene, seq); + + WM_main_add_notifier(NC_SCENE | ND_SEQUENCER, NULL); } static void rna_Sequence_modifier_clear(Sequence *seq, bContext *C) @@ -1267,7 +1269,8 @@ static void rna_def_sequence_modifiers(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_ui_description(func, "Remove an existing modifier from the sequence"); /* modifier to remove */ parm = RNA_def_pointer(func, "modifier", "SequenceModifier", "", "Modifier to remove"); - RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); /* clear all modifiers */ func = RNA_def_function(srna, "clear", "rna_Sequence_modifier_clear"); diff --git a/source/blender/makesrna/intern/rna_sequencer_api.c b/source/blender/makesrna/intern/rna_sequencer_api.c index c5a0408c7a0..8ddb9d0a7e7 100644 --- a/source/blender/makesrna/intern/rna_sequencer_api.c +++ b/source/blender/makesrna/intern/rna_sequencer_api.c @@ -308,12 +308,18 @@ static Sequence *rna_Sequences_new_effect(ID *id, Editing *ed, ReportList *repor return seq; } -static void rna_Sequences_remove(ID *id, Editing *ed, Sequence *seq) +static void rna_Sequences_remove(ID *id, Editing *ed, ReportList *reports, PointerRNA *seq_ptr) { + Sequence *seq = seq_ptr->data; Scene *scene = (Scene *)id; - BLI_remlink(&ed->seqbase, seq); + if (BLI_remlink_safe(&ed->seqbase, seq) == FALSE) { + BKE_reportf(reports, RPT_ERROR, "Sequence '%s' not in scene '%s'", seq->name + 2, scene->id.name + 2); + return; + } + BKE_sequence_free(scene, seq); + RNA_POINTER_INVALIDATE(seq_ptr); WM_main_add_notifier(NC_SCENE | ND_SEQUENCER, scene); } @@ -568,21 +574,22 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop) parm = RNA_def_int(func, "start_frame", 0, -MAXFRAME, MAXFRAME, "", "The start frame for the new sequence", -MAXFRAME, MAXFRAME); RNA_def_property_flag(parm, PROP_REQUIRED); - parm = RNA_def_int(func, "end_frame", 0, -MAXFRAME, MAXFRAME, "", - "The end frame for the new sequence", -MAXFRAME, MAXFRAME); - parm = RNA_def_pointer(func, "seq1", "Sequence", "", "Sequence 1 for effect"); - parm = RNA_def_pointer(func, "seq2", "Sequence", "", "Sequence 2 for effect"); - parm = RNA_def_pointer(func, "seq3", "Sequence", "", "Sequence 3 for effect"); + RNA_def_int(func, "end_frame", 0, -MAXFRAME, MAXFRAME, "", + "The end frame for the new sequence", -MAXFRAME, MAXFRAME); + RNA_def_pointer(func, "seq1", "Sequence", "", "Sequence 1 for effect"); + RNA_def_pointer(func, "seq2", "Sequence", "", "Sequence 2 for effect"); + RNA_def_pointer(func, "seq3", "Sequence", "", "Sequence 3 for effect"); /* return type */ parm = RNA_def_pointer(func, "sequence", "Sequence", "", "New Sequence"); RNA_def_function_return(func, parm); func = RNA_def_function(srna, "remove", "rna_Sequences_remove"); - RNA_def_function_flag(func, FUNC_USE_SELF_ID); + RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_REPORTS); RNA_def_function_ui_description(func, "Remove a Sequence"); parm = RNA_def_pointer(func, "sequence", "Sequence", "", "Sequence to remove"); - RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); } diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index ecb2bf71cb2..70daba9790f 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -958,15 +958,17 @@ static BGpic *rna_BackgroundImage_new(View3D *v3d) return bgpic; } -static void rna_BackgroundImage_remove(View3D *v3d, ReportList *reports, BGpic *bgpic) +static void rna_BackgroundImage_remove(View3D *v3d, ReportList *reports, PointerRNA *bgpic_ptr) { + BGpic *bgpic = bgpic_ptr->data; if (BLI_findindex(&v3d->bgpicbase, bgpic) == -1) { BKE_report(reports, RPT_ERROR, "Background image cannot be removed"); } - else { - ED_view3D_background_image_remove(v3d, bgpic); - WM_main_add_notifier(NC_SPACE | ND_SPACE_VIEW3D, v3d); - } + + ED_view3D_background_image_remove(v3d, bgpic); + RNA_POINTER_INVALIDATE(bgpic_ptr); + + WM_main_add_notifier(NC_SPACE | ND_SPACE_VIEW3D, v3d); } static void rna_BackgroundImage_clear(View3D *v3d) @@ -1451,7 +1453,8 @@ static void rna_def_backgroundImages(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_ui_description(func, "Remove background image"); RNA_def_function_flag(func, FUNC_USE_REPORTS); parm = RNA_def_pointer(func, "image", "BackgroundImage", "", "Image displayed as viewport background"); - RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); func = RNA_def_function(srna, "clear", "rna_BackgroundImage_clear"); RNA_def_function_ui_description(func, "Remove all background images"); diff --git a/source/blender/makesrna/intern/rna_tracking.c b/source/blender/makesrna/intern/rna_tracking.c index 4b744b160fc..365b80b6d7c 100644 --- a/source/blender/makesrna/intern/rna_tracking.c +++ b/source/blender/makesrna/intern/rna_tracking.c @@ -35,6 +35,7 @@ #include "BKE_movieclip.h" #include "BKE_tracking.h" +#include "RNA_access.h" #include "RNA_define.h" #include "rna_internal.h" @@ -447,9 +448,15 @@ static MovieTrackingObject *rna_trackingObject_new(MovieTracking *tracking, cons return object; } -static void rna_trackingObject_remove(MovieTracking *tracking, MovieTrackingObject *object) +static void rna_trackingObject_remove(MovieTracking *tracking, ReportList *reports, PointerRNA *object_ptr) { - BKE_tracking_object_delete(tracking, object); + MovieTrackingObject *object = object_ptr->data; + if (BKE_tracking_object_delete(tracking, object) == FALSE) { + BKE_reportf(reports, RPT_ERROR, "MovieTracking '%s' can't be removed", object->name); + return; + } + + RNA_POINTER_INVALIDATE(object_ptr); WM_main_add_notifier(NC_MOVIECLIP | NA_EDITED, NULL); } @@ -897,8 +904,8 @@ static void rna_def_trackingMarkers(BlenderRNA *brna, PropertyRNA *cprop) parm = RNA_def_int(func, "frame", 1, MINFRAME, MAXFRAME, "Frame", "Frame number to find marker for", MINFRAME, MAXFRAME); RNA_def_property_flag(parm, PROP_REQUIRED); - parm = RNA_def_boolean(func, "exact", TRUE, "Exact", - "Get marker at exact frame number rather than get estimated marker"); + RNA_def_boolean(func, "exact", TRUE, "Exact", + "Get marker at exact frame number rather than get estimated marker"); parm = RNA_def_pointer(func, "marker", "MovieTrackingMarker", "", "Marker for specified frame"); RNA_def_function_return(func, parm); @@ -1416,8 +1423,11 @@ static void rna_def_trackingObjects(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_return(func, parm); func = RNA_def_function(srna, "remove", "rna_trackingObject_remove"); + RNA_def_function_flag(func, FUNC_USE_REPORTS); RNA_def_function_ui_description(func, "Remove tracking object from this movie clip"); - RNA_def_pointer(func, "object", "MovieTrackingObject", "", "Motion tracking object to be removed"); + parm = RNA_def_pointer(func, "object", "MovieTrackingObject", "", "Motion tracking object to be removed"); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); /* active object */ prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index fc30c02341a..c49f67d49fe 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -24,9 +24,9 @@ * \ingroup RNA */ - #include <stdlib.h> +#include "RNA_access.h" #include "RNA_define.h" #include "RNA_enum_types.h" @@ -311,9 +311,16 @@ static bAddon *rna_userdef_addon_new(void) return bext; } -static void rna_userdef_addon_remove(bAddon *bext) +static void rna_userdef_addon_remove(ReportList *reports, PointerRNA *bext_ptr) { + bAddon *bext = bext_ptr->data; + if (BLI_findindex(&U.addons, bext) == -1) { + BKE_report(reports, RPT_ERROR, "Addon is no longer valid"); + return; + } + BLI_freelinkN(&U.addons, bext); + RNA_POINTER_INVALIDATE(bext_ptr); } static void rna_userdef_temp_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *UNUSED(ptr)) @@ -3659,10 +3666,11 @@ static void rna_def_userdef_addon_collection(BlenderRNA *brna, PropertyRNA *cpro RNA_def_function_return(func, parm); func = RNA_def_function(srna, "remove", "rna_userdef_addon_remove"); - RNA_def_function_flag(func, FUNC_NO_SELF); + RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_USE_REPORTS); RNA_def_function_ui_description(func, "Remove addon"); parm = RNA_def_pointer(func, "addon", "Addon", "", "Addon to remove"); - RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); } void RNA_def_userdef(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c index 23587bf6cd6..e5f44644f7a 100644 --- a/source/blender/makesrna/intern/rna_wm.c +++ b/source/blender/makesrna/intern/rna_wm.c @@ -122,6 +122,7 @@ EnumPropertyItem event_timer_type_items[] = { }; EnumPropertyItem event_ndof_type_items[] = { + {NDOF_MOTION, "NDOF_MOTION", 0, "Motion", ""}, /* buttons on all 3dconnexion devices */ {NDOF_BUTTON_MENU, "NDOF_BUTTON_MENU", 0, "Menu", ""}, {NDOF_BUTTON_FIT, "NDOF_BUTTON_FIT", 0, "Fit", ""}, @@ -622,8 +623,8 @@ static void rna_wmKeyMapItem_map_type_set(PointerRNA *ptr, int value) kmi->val = KM_NOTHING; break; case KMI_TYPE_NDOF: - kmi->type = NDOF_BUTTON_MENU; - kmi->val = KM_PRESS; + kmi->type = NDOF_MOTION; + kmi->val = KM_NOTHING; break; } } diff --git a/source/blender/makesrna/intern/rna_wm_api.c b/source/blender/makesrna/intern/rna_wm_api.c index d6979161cdc..116e07073cd 100644 --- a/source/blender/makesrna/intern/rna_wm_api.c +++ b/source/blender/makesrna/intern/rna_wm_api.c @@ -153,6 +153,18 @@ static wmKeyMapItem *rna_KeyMap_item_new_modal(wmKeyMap *km, ReportList *reports return WM_modalkeymap_add_item(km, type, value, modifier, keymodifier, propvalue); } +static void rna_KeyMap_item_remove(wmKeyMap *km, ReportList *reports, PointerRNA *kmi_ptr) +{ + wmKeyMapItem *kmi = kmi_ptr->data; + + if (WM_keymap_remove_item(km, kmi) == FALSE) { + BKE_reportf(reports, RPT_ERROR, "KeyMapItem '%s' can't be removed from '%s'", kmi->idname, km->idname); + return; + } + + RNA_POINTER_INVALIDATE(kmi_ptr); +} + static wmKeyMap *rna_keymap_new(wmKeyConfig *keyconf, const char *idname, int spaceid, int regionid, int modal) { if (modal == 0) { @@ -178,6 +190,18 @@ static wmKeyMap *rna_keymap_find_modal(wmKeyConfig *UNUSED(keyconf), const char return ot->modalkeymap; } +static void rna_KeyConfig_remove(wmWindowManager *wm, ReportList *reports, PointerRNA *keyconf_ptr) +{ + wmKeyConfig *keyconf = keyconf_ptr->data; + + if (WM_keyconfig_remove(wm, keyconf) == FALSE) { + BKE_reportf(reports, RPT_ERROR, "KeyConfig '%s' can't be removed", keyconf->idname); + return; + } + + RNA_POINTER_INVALIDATE(keyconf_ptr); +} + #else #define WM_GEN_INVOKE_EVENT (1 << 0) @@ -292,7 +316,7 @@ void RNA_api_operator(StructRNA *srna) /* exec */ func = RNA_def_function(srna, "execute", NULL); RNA_def_function_ui_description(func, "Execute the operator"); - RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL); + RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL | FUNC_ALLOW_WRITE); parm = RNA_def_pointer(func, "context", "Context", "", ""); RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); @@ -303,7 +327,7 @@ void RNA_api_operator(StructRNA *srna) /* check */ func = RNA_def_function(srna, "check", NULL); RNA_def_function_ui_description(func, "Check the operator settings, return True to signal a change to redraw"); - RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL); + RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL | FUNC_ALLOW_WRITE); parm = RNA_def_pointer(func, "context", "Context", "", ""); RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); @@ -313,7 +337,7 @@ void RNA_api_operator(StructRNA *srna) /* invoke */ func = RNA_def_function(srna, "invoke", NULL); RNA_def_function_ui_description(func, "Invoke the operator"); - RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL); + RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL | FUNC_ALLOW_WRITE); parm = RNA_def_pointer(func, "context", "Context", "", ""); RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); parm = RNA_def_pointer(func, "event", "Event", "", ""); @@ -325,7 +349,7 @@ void RNA_api_operator(StructRNA *srna) func = RNA_def_function(srna, "modal", NULL); /* same as invoke */ RNA_def_function_ui_description(func, "Modal operator function"); - RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL); + RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL | FUNC_ALLOW_WRITE); parm = RNA_def_pointer(func, "context", "Context", "", ""); RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); parm = RNA_def_pointer(func, "event", "Event", "", ""); @@ -345,7 +369,7 @@ void RNA_api_operator(StructRNA *srna) /* cancel */ func = RNA_def_function(srna, "cancel", NULL); RNA_def_function_ui_description(func, "Called when the operator is canceled"); - RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL); + RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL | FUNC_ALLOW_WRITE); parm = RNA_def_pointer(func, "context", "Context", "", ""); RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); @@ -464,9 +488,11 @@ void RNA_api_keymapitems(StructRNA *srna) parm = RNA_def_pointer(func, "item", "KeyMapItem", "Item", "Added key map item"); RNA_def_function_return(func, parm); - func = RNA_def_function(srna, "remove", "WM_keymap_remove_item"); + func = RNA_def_function(srna, "remove", "rna_KeyMap_item_remove"); + RNA_def_function_flag(func, FUNC_USE_REPORTS); parm = RNA_def_pointer(func, "item", "KeyMapItem", "Item", ""); - RNA_def_property_flag(parm, PROP_REQUIRED); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); func = RNA_def_function(srna, "from_id", "WM_keymap_item_find_id"); parm = RNA_def_property(func, "id", PROP_INT, PROP_NONE); @@ -516,10 +542,11 @@ void RNA_api_keyconfigs(StructRNA *srna) parm = RNA_def_pointer(func, "keyconfig", "KeyConfig", "Key Configuration", "Added key configuration"); RNA_def_function_return(func, parm); - func = RNA_def_function(srna, "remove", "WM_keyconfig_remove"); /* remove_keyconfig */ + func = RNA_def_function(srna, "remove", "rna_KeyConfig_remove"); /* remove_keyconfig */ + RNA_def_function_flag(func, FUNC_USE_REPORTS); parm = RNA_def_pointer(func, "keyconfig", "KeyConfig", "Key Configuration", "Removed key configuration"); - RNA_def_property_flag(parm, PROP_REQUIRED); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL | PROP_RNAPTR); + RNA_def_property_clear_flag(parm, PROP_THICK_WRAP); } #endif - diff --git a/source/blender/modifiers/intern/MOD_array.c b/source/blender/modifiers/intern/MOD_array.c index 7b699e5633c..b9dd37ac50c 100644 --- a/source/blender/modifiers/intern/MOD_array.c +++ b/source/blender/modifiers/intern/MOD_array.c @@ -314,7 +314,8 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd, BMesh *bm = DM_to_bmesh(dm); BMOperator first_dupe_op, dupe_op, old_dupe_op, weld_op; BMVert **first_geom = NULL; - int i, j, indexLen; + int i, j; + int index_len = -1; /* initialize to an invalid value */ /* offset matrix */ float offset[4][4]; float final_offset[4][4]; @@ -452,12 +453,15 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd, /*calculate merge mapping*/ if (j == 0) { indexMap = find_doubles_index_map(bm, &dupe_op, - amd, &indexLen); + amd, &index_len); } #define _E(s, i) ((BMVert **)(s)->data.buf)[i] - for (i = 0; i < indexLen; i++) { + /* ensure this is set */ + BLI_assert(index_len != -1); + + for (i = 0; i < index_len; i++) { if (!indexMap[i]) continue; /* merge v (from 'newout') into v2 (from old 'geom') */ diff --git a/source/blender/modifiers/intern/MOD_boolean_util.c b/source/blender/modifiers/intern/MOD_boolean_util.c index bded11ddfa7..2ff93532d14 100644 --- a/source/blender/modifiers/intern/MOD_boolean_util.c +++ b/source/blender/modifiers/intern/MOD_boolean_util.c @@ -361,9 +361,9 @@ static DerivedMesh *ConvertCSGDescriptorsToDerivedMesh( /* create a new DerivedMesh */ result = CDDM_new(vertex_it->num_elements, 0, face_it->num_elements, 0, 0); - CustomData_merge(&dm1->faceData, &result->faceData, CD_MASK_DERIVEDMESH & ~(CD_MASK_NORMAL | CD_MASK_POLYINDEX | CD_MASK_ORIGINDEX), + CustomData_merge(&dm1->faceData, &result->faceData, CD_MASK_DERIVEDMESH & ~(CD_MASK_NORMAL | CD_MASK_ORIGINDEX), CD_DEFAULT, face_it->num_elements); - CustomData_merge(&dm2->faceData, &result->faceData, CD_MASK_DERIVEDMESH & ~(CD_MASK_NORMAL | CD_MASK_POLYINDEX | CD_MASK_ORIGINDEX), + CustomData_merge(&dm2->faceData, &result->faceData, CD_MASK_DERIVEDMESH & ~(CD_MASK_NORMAL | CD_MASK_ORIGINDEX), CD_DEFAULT, face_it->num_elements); /* step through the vertex iterators: */ diff --git a/source/blender/modifiers/intern/MOD_explode.c b/source/blender/modifiers/intern/MOD_explode.c index 0e4aa54b4c1..92ad6faa3ce 100644 --- a/source/blender/modifiers/intern/MOD_explode.c +++ b/source/blender/modifiers/intern/MOD_explode.c @@ -669,8 +669,7 @@ static DerivedMesh *cutEdges(ExplodeModifierData *emd, DerivedMesh *dm) mv = CDDM_get_vert(splitdm, ed_v1); - add_v3_v3(dupve->co, mv->co); - mul_v3_fl(dupve->co, 0.5f); + mid_v3_v3v3(dupve->co, dupve->co, mv->co); } BLI_edgehashIterator_free(ehi); diff --git a/source/blender/modifiers/intern/MOD_laplaciansmooth.c b/source/blender/modifiers/intern/MOD_laplaciansmooth.c index eb05cecd932..6f6589d4d14 100644 --- a/source/blender/modifiers/intern/MOD_laplaciansmooth.c +++ b/source/blender/modifiers/intern/MOD_laplaciansmooth.c @@ -52,8 +52,8 @@ #include "ONL_opennl.h" -#define MOD_LAPLACIANSMOOTH_MAX_EDGE_PERCENTAGE 1.8 -#define MOD_LAPLACIANSMOOTH_MIN_EDGE_PERCENTAGE 0.02 +#define MOD_LAPLACIANSMOOTH_MAX_EDGE_PERCENTAGE 1.8f +#define MOD_LAPLACIANSMOOTH_MIN_EDGE_PERCENTAGE 0.02f struct BLaplacianSystem { float *eweights; /* Length weights per Edge */ @@ -279,13 +279,13 @@ static float compute_volume(float (*vertexCos)[3], MFace *mfaces, int numFaces) z3 = vf[2][2]; - vol += (1.0 / 6.0) * (x2 * y3 * z1 + x3 * y1 * z2 - x1 * y3 * z2 - x2 * y1 * z3 + x1 * y2 * z3 - x3 * y2 * z1); + vol += (1.0f / 6.0f) * (x2 * y3 * z1 + x3 * y1 * z2 - x1 * y3 * z2 - x2 * y1 * z3 + x1 * y2 * z3 - x3 * y2 * z1); if ((&mfaces[i])->v4) { vf[3] = vertexCos[mfaces[i].v4]; x4 = vf[3][0]; y4 = vf[3][1]; z4 = vf[3][2]; - vol += (1.0 / 6.0) * (x1 * y3 * z4 - x1 * y4 * z3 - x3 * y1 * z4 + x3 * z1 * y4 + y1 * x4 * z3 - x4 * y3 * z1); + vol += (1.0f / 6.0f) * (x1 * y3 * z4 - x1 * y4 * z3 - x3 * y1 * z4 + x3 * z1 * y4 + y1 * x4 * z3 - x4 * y3 * z1); } } return fabsf(vol); @@ -365,7 +365,7 @@ static void init_laplacian_matrix(LaplacianSystem *sys) else { areaf = area_tri_v3(v1, v2, v3); } - if (fabs(areaf) < sys->min_area) { + if (fabsf(areaf) < sys->min_area) { sys->zerola[idv1] = 1; sys->zerola[idv2] = 1; sys->zerola[idv3] = 1; @@ -552,8 +552,8 @@ static void validate_solution(LaplacianSystem *sys, short flag) } static void laplaciansmoothModifier_do( - LaplacianSmoothModifierData *smd, Object *ob, DerivedMesh *dm, - float (*vertexCos)[3], int numVerts) + LaplacianSmoothModifierData *smd, Object *ob, DerivedMesh *dm, + float (*vertexCos)[3], int numVerts) { LaplacianSystem *sys; MDeformVert *dvert = NULL; diff --git a/source/blender/modifiers/intern/MOD_mask.c b/source/blender/modifiers/intern/MOD_mask.c index f845f1d9dc7..23ce8cdeb21 100644 --- a/source/blender/modifiers/intern/MOD_mask.c +++ b/source/blender/modifiers/intern/MOD_mask.c @@ -179,7 +179,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, } /* verthash gives mapping from original vertex indices to the new indices (including selected matches only) - * key=oldindex, value=newindex + * key = oldindex, value = newindex */ vertHash = BLI_ghash_int_new("mask vert gh"); diff --git a/source/blender/modifiers/intern/MOD_ocean.c b/source/blender/modifiers/intern/MOD_ocean.c index 5cef59a462b..564fa696c2a 100644 --- a/source/blender/modifiers/intern/MOD_ocean.c +++ b/source/blender/modifiers/intern/MOD_ocean.c @@ -33,17 +33,17 @@ #include "DNA_modifier_types.h" #include "DNA_scene_types.h" -#include "BKE_cdderivedmesh.h" -#include "BKE_global.h" -#include "BKE_modifier.h" -#include "BKE_ocean.h" - #include "BLI_blenlib.h" #include "BLI_math.h" #include "BLI_math_inline.h" #include "BLI_utildefines.h" #include "BLI_string.h" +#include "BKE_cdderivedmesh.h" +#include "BKE_global.h" +#include "BKE_modifier.h" +#include "BKE_ocean.h" + #include "MOD_util.h" #ifdef WITH_OCEANSIM diff --git a/source/blender/modifiers/intern/MOD_skin.c b/source/blender/modifiers/intern/MOD_skin.c index 5cc38ff0489..8a4d70da6e8 100644 --- a/source/blender/modifiers/intern/MOD_skin.c +++ b/source/blender/modifiers/intern/MOD_skin.c @@ -697,11 +697,11 @@ static void build_emats_stack(BLI_Stack *stack, int *visited_e, EMat *emat, } static EMat *build_edge_mats(const MVertSkin *vs, - const MVert *mvert, - int totvert, + const MVert *mvert, + int totvert, const MEdge *medge, - const MeshElemMap *emap, - int totedge) + const MeshElemMap *emap, + int totedge) { BLI_Stack *stack; EMat *emat; diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt index 19b3df8affe..323a534c989 100644 --- a/source/blender/nodes/CMakeLists.txt +++ b/source/blender/nodes/CMakeLists.txt @@ -165,6 +165,7 @@ set(SRC shader/nodes/node_shader_light_path.c shader/nodes/node_shader_light_falloff.c shader/nodes/node_shader_object_info.c + shader/nodes/node_shader_script.c shader/nodes/node_shader_particle_info.c shader/nodes/node_shader_mix_shader.c shader/nodes/node_shader_add_shader.c diff --git a/source/blender/nodes/NOD_shader.h b/source/blender/nodes/NOD_shader.h index 7585ed0d61c..66ab15ce29f 100644 --- a/source/blender/nodes/NOD_shader.h +++ b/source/blender/nodes/NOD_shader.h @@ -80,6 +80,7 @@ void register_node_type_sh_fresnel(struct bNodeTreeType *ttype); void register_node_type_sh_layer_weight(struct bNodeTreeType *ttype); void register_node_type_sh_tex_coord(struct bNodeTreeType *ttype); void register_node_type_sh_particle_info(struct bNodeTreeType *ttype); +void register_node_type_sh_script(struct bNodeTreeType *ttype); void register_node_type_sh_background(struct bNodeTreeType *ttype); void register_node_type_sh_bsdf_diffuse(struct bNodeTreeType *ttype); diff --git a/source/blender/nodes/shader/node_shader_tree.c b/source/blender/nodes/shader/node_shader_tree.c index 76bc3b12690..b7dc83d7d79 100644 --- a/source/blender/nodes/shader/node_shader_tree.c +++ b/source/blender/nodes/shader/node_shader_tree.c @@ -87,10 +87,11 @@ static void foreach_nodeclass(Scene *scene, void *calldata, bNodeClassCallback f func(calldata, NODE_CLASS_SHADER, N_("Shader")); func(calldata, NODE_CLASS_TEXTURE, N_("Texture")); } - + func(calldata, NODE_CLASS_OP_COLOR, N_("Color")); func(calldata, NODE_CLASS_OP_VECTOR, N_("Vector")); func(calldata, NODE_CLASS_CONVERTOR, N_("Convertor")); + func(calldata, NODE_CLASS_SCRIPT, N_("Script")); func(calldata, NODE_CLASS_GROUP, N_("Group")); func(calldata, NODE_CLASS_LAYOUT, N_("Layout")); } diff --git a/source/blender/nodes/shader/nodes/node_shader_script.c b/source/blender/nodes/shader/nodes/node_shader_script.c new file mode 100644 index 00000000000..52d39363de6 --- /dev/null +++ b/source/blender/nodes/shader/nodes/node_shader_script.c @@ -0,0 +1,85 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2005 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/nodes/shader/nodes/node_shader_script.c + * \ingroup shdnodes + */ + +#include "BKE_idprop.h" + +#include "node_shader_util.h" + +/* **************** Script ******************** */ + +static void init(bNodeTree *UNUSED(ntree), bNode *node, bNodeTemplate *UNUSED(ntemp)) +{ + NodeShaderScript *nss = MEM_callocN(sizeof(NodeShaderScript), "shader script node"); + node->storage = nss; +} + +static void node_free_script(bNode *node) +{ + NodeShaderScript *nss = node->storage; + + if (nss) { + if (nss->bytecode) + MEM_freeN(nss->bytecode); + + MEM_freeN(nss); + } + + if (nss->prop) { + IDP_FreeProperty(nss->prop); + MEM_freeN(nss->prop); + } +} + +static void node_copy_script(bNode *orig_node, bNode *new_node) +{ + NodeShaderScript *orig_nss = orig_node->storage; + NodeShaderScript *new_nss = MEM_dupallocN(orig_nss); + + if(orig_nss->bytecode) + new_nss->bytecode = MEM_dupallocN(orig_nss->bytecode); + + if (orig_nss->prop) + new_nss->prop = IDP_CopyProperty(orig_nss->prop); + + new_node->storage = new_nss; +} + +void register_node_type_sh_script(bNodeTreeType *ttype) +{ + static bNodeType ntype; + + node_type_base(ttype, &ntype, SH_NODE_SCRIPT, "Script", NODE_CLASS_SCRIPT, NODE_OPTIONS); + node_type_compatibility(&ntype, NODE_NEW_SHADING); + node_type_init(&ntype, init); + node_type_storage(&ntype, "NodeShaderScript", node_free_script, node_copy_script); + + nodeRegisterType(ttype, &ntype); +} diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_environment.c b/source/blender/nodes/shader/nodes/node_shader_tex_environment.c index 30bfe1704ae..abe8e0190c8 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_environment.c +++ b/source/blender/nodes/shader/nodes/node_shader_tex_environment.c @@ -83,7 +83,7 @@ static int node_shader_gpu_tex_environment(GPUMaterial *mat, bNode *node, GPUNod } } - return ret; + return ret; } /* node type definition */ diff --git a/source/blender/python/generic/idprop_py_api.c b/source/blender/python/generic/idprop_py_api.c index d4ec8137399..d2890bc046e 100644 --- a/source/blender/python/generic/idprop_py_api.c +++ b/source/blender/python/generic/idprop_py_api.c @@ -43,43 +43,39 @@ #include "py_capi_utils.h" #endif -extern PyTypeObject BPy_IDArray_Type; -extern PyTypeObject BPy_IDGroup_Iter_Type; -extern PyTypeObject BPy_IDGroup_Type; - /*********************** ID Property Main Wrapper Stuff ***************/ /* ---------------------------------------------------------------------------- * static conversion functions to avoid duplicate code, no type checking. */ -static PyObject *idprop_py_from_idp_string(IDProperty *prop) +static PyObject *idprop_py_from_idp_string(const IDProperty *prop) { if (prop->subtype == IDP_STRING_SUB_BYTE) { - return PyBytes_FromStringAndSize(IDP_Array(prop), prop->len); + return PyBytes_FromStringAndSize(IDP_String(prop), prop->len); } else { #ifdef USE_STRING_COERCE return PyC_UnicodeFromByteAndSize(IDP_Array(prop), prop->len - 1); #else - return PyUnicode_FromStringAndSize(IDP_Array(prop), prop->len - 1); + return PyUnicode_FromStringAndSize(IDP_String(prop), prop->len - 1); #endif } } -static PyObject *idprop_py_from_idp_int(IDProperty *prop) +static PyObject *idprop_py_from_idp_int(const IDProperty *prop) { - return PyLong_FromLong((long)prop->data.val); + return PyLong_FromLong((long)IDP_Int(prop)); } -static PyObject *idprop_py_from_idp_float(IDProperty *prop) +static PyObject *idprop_py_from_idp_float(const IDProperty *prop) { - return PyFloat_FromDouble((double)(*(float *)(&prop->data.val))); + return PyFloat_FromDouble((double)IDP_Float(prop)); } -static PyObject *idprop_py_from_idp_double(IDProperty *prop) +static PyObject *idprop_py_from_idp_double(const IDProperty *prop) { - return PyFloat_FromDouble((*(double *)(&prop->data.val))); + return PyFloat_FromDouble(IDP_Double(prop)); } static PyObject *idprop_py_from_idp_group(ID *id, IDProperty *prop, IDProperty *parent) @@ -193,7 +189,7 @@ static int BPy_IDGroup_SetData(BPy_IDProperty *self, IDProperty *prop, PyObject PyErr_SetString(PyExc_TypeError, "expected an int type"); return -1; } - prop->data.val = ivalue; + IDP_Int(prop) = ivalue; break; } case IDP_FLOAT: @@ -203,7 +199,7 @@ static int BPy_IDGroup_SetData(BPy_IDProperty *self, IDProperty *prop, PyObject PyErr_SetString(PyExc_TypeError, "expected a float"); return -1; } - *(float *)&self->prop->data.val = fvalue; + IDP_Float(self->prop) = fvalue; break; } case IDP_DOUBLE: @@ -213,7 +209,7 @@ static int BPy_IDGroup_SetData(BPy_IDProperty *self, IDProperty *prop, PyObject PyErr_SetString(PyExc_TypeError, "expected a float"); return -1; } - *(double *)&self->prop->data.val = dvalue; + IDP_Double(self->prop) = dvalue; break; } default: @@ -809,17 +805,28 @@ static PyObject *BPy_IDGroup_Update(BPy_IDProperty *self, PyObject *value) PyObject *pkey, *pval; Py_ssize_t i = 0; - if (!PyDict_Check(value)) { + if (BPy_IDGroup_Check(value)) { + BPy_IDProperty *other = (BPy_IDProperty *)value; + if (UNLIKELY(self->prop == other->prop)) { + Py_RETURN_NONE; + } + + /* XXX, possible one is inside the other */ + IDP_MergeGroup(self->prop, other->prop, TRUE); + } + else if (PyDict_Check(value)) { + while (PyDict_Next(value, &i, &pkey, &pval)) { + BPy_IDGroup_Map_SetItem(self, pkey, pval); + if (PyErr_Occurred()) return NULL; + } + } + else { PyErr_Format(PyExc_TypeError, - "expected a dict not a %.200s", + "expected a dict or an IDPropertyGroup type, not a %.200s", Py_TYPE(value)->tp_name); return NULL; } - while (PyDict_Next(value, &i, &pkey, &pval)) { - BPy_IDGroup_Map_SetItem(self, pkey, pval); - if (PyErr_Occurred()) return NULL; - } Py_RETURN_NONE; } @@ -1423,15 +1430,15 @@ void IDProp_Init_Types(void) /* --- */ static struct PyModuleDef IDProp_types_module_def = { - PyModuleDef_HEAD_INIT, - "idprop.types", /* m_name */ - NULL, /* m_doc */ - 0, /* m_size */ - NULL, /* m_methods */ - NULL, /* m_reload */ - NULL, /* m_traverse */ - NULL, /* m_clear */ - NULL, /* m_free */ + PyModuleDef_HEAD_INIT, + "idprop.types", /* m_name */ + NULL, /* m_doc */ + 0, /* m_size */ + NULL, /* m_methods */ + NULL, /* m_reload */ + NULL, /* m_traverse */ + NULL, /* m_clear */ + NULL, /* m_free */ }; static PyObject *BPyInit_idprop_types(void) @@ -1490,3 +1497,40 @@ PyObject *BPyInit_idprop(void) return mod; } + + +#ifdef DEBUG +/* -------------------------------------------------------------------- */ +/* debug only function */ + +void IDP_spit(IDProperty *prop) +{ + if (prop) { + PyGILState_STATE gilstate; + int use_gil = TRUE; /* !PYC_INTERPRETER_ACTIVE; */ + PyObject *ret_dict; + PyObject *ret_str; + + if (use_gil) { + gilstate = PyGILState_Ensure(); + } + + /* to_dict() */ + ret_dict = BPy_IDGroup_MapDataToPy(prop); + ret_str = PyObject_Repr(ret_dict); + Py_DECREF(ret_dict); + + printf("IDProperty: %s\n", _PyUnicode_AsString(ret_str)); + + Py_DECREF(ret_str); + + if (use_gil) { + PyGILState_Release(gilstate); + } + } + else { + printf("IDProperty: <NIL>\n"); + } +} + +#endif diff --git a/source/blender/python/generic/idprop_py_api.h b/source/blender/python/generic/idprop_py_api.h index 99e291f69c0..cb82676c4d9 100644 --- a/source/blender/python/generic/idprop_py_api.h +++ b/source/blender/python/generic/idprop_py_api.h @@ -32,6 +32,17 @@ struct ID; struct IDProperty; struct BPy_IDGroup_Iter; +extern PyTypeObject BPy_IDArray_Type; +extern PyTypeObject BPy_IDGroup_Iter_Type; +extern PyTypeObject BPy_IDGroup_Type; + +#define BPy_IDArray_Check(v) (PyObject_TypeCheck(v, &BPy_IDArray_Type)) +#define BPy_IDArray_CheckExact(v) (Py_TYPE(v) == &BPy_IDArray_Type) +#define BPy_IDGroup_Iter_Check(v) (PyObject_TypeCheck(v, &BPy_IDGroup_Iter_Type)) +#define BPy_IDGroup_Iter_CheckExact(v) (Py_TYPE(v) == &BPy_IDGroup_Iter_Type) +#define BPy_IDGroup_Check(v) (PyObject_TypeCheck(v, &BPy_IDGroup_Type)) +#define BPy_IDGroup_CheckExact(v) (Py_TYPE(v) == &BPy_IDGroup_Type) + typedef struct BPy_IDProperty { PyObject_VAR_HEAD struct ID *id; /* can be NULL */ diff --git a/source/blender/python/intern/bpy_props.c b/source/blender/python/intern/bpy_props.c index 164c9fec110..bd033736865 100644 --- a/source/blender/python/intern/bpy_props.c +++ b/source/blender/python/intern/bpy_props.c @@ -75,7 +75,7 @@ static EnumPropertyItem property_flag_enum_items[] = { static EnumPropertyItem property_subtype_string_items[] = { {PROP_FILEPATH, "FILE_PATH", 0, "File Path", ""}, {PROP_DIRPATH, "DIR_PATH", 0, "Directory Path", ""}, - {PROP_FILENAME, "FILENAME", 0, "Filename", ""}, + {PROP_FILENAME, "FILE_NAME", 0, "Filename", ""}, {PROP_BYTESTRING, "BYTE_STRING", 0, "Byte String", ""}, {PROP_TRANSLATE, "TRANSLATE", 0, "Translate", ""}, {PROP_PASSWORD, "PASSWORD", 0, "Password", 0}, @@ -310,35 +310,38 @@ static int py_long_as_int(PyObject *py_long, int *r_int) /* terse macros for error checks shared between all funcs cant use function * calls because of static strings passed to pyrna_set_to_enum_bitfield */ #define BPY_PROPDEF_CHECK(_func, _property_flag_items) \ - if (id_len >= MAX_IDPROP_NAME) { \ + if (UNLIKELY(id_len >= MAX_IDPROP_NAME)) { \ PyErr_Format(PyExc_TypeError, \ #_func"(): '%.200s' too long, max length is %d", \ id, MAX_IDPROP_NAME - 1); \ return NULL; \ } \ - if (RNA_def_property_free_identifier(srna, id) == -1) { \ + if (UNLIKELY(RNA_def_property_free_identifier(srna, id) == -1)) { \ PyErr_Format(PyExc_TypeError, \ #_func"(): '%s' is defined as a non-dynamic type", \ id); \ return NULL; \ } \ - if (pyopts && pyrna_set_to_enum_bitfield(_property_flag_items, \ + if (UNLIKELY(pyopts && pyrna_set_to_enum_bitfield(_property_flag_items, \ pyopts, \ &opts, \ - #_func"(options={ ...}):")) \ + #_func"(options={ ...}):"))) \ { \ return NULL; \ } (void)0 #define BPY_PROPDEF_SUBTYPE_CHECK(_func, _property_flag_items, _subtype) \ BPY_PROPDEF_CHECK(_func, _property_flag_items); \ - if (pysubtype && RNA_enum_value_from_id(_subtype, \ + if (UNLIKELY(pysubtype && RNA_enum_value_from_id(_subtype, \ pysubtype, \ - &subtype) == 0) \ + &subtype) == 0)) \ { \ + const char *enum_str = BPy_enum_as_string(_subtype); \ PyErr_Format(PyExc_TypeError, \ - #_func"(subtype='%s'): invalid subtype", \ - pysubtype); \ + #_func"(subtype='%s'): " \ + "subtype not found in (%s)", \ + pysubtype, enum_str); \ + MEM_freeN((void *)enum_str); \ return NULL; \ } (void)0 @@ -922,7 +925,7 @@ BPY_PROPDEF_NAME_DOC BPY_PROPDEF_DESC_DOC " :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE', 'LIBRARY_EDITABLE'].\n" " :type options: set\n" -" :arg subtype: Enumerator in ['FILE_PATH', 'DIR_PATH', 'FILENAME', 'NONE'].\n" +" :arg subtype: Enumerator in ['FILE_PATH', 'DIR_PATH', 'FILE_NAME', 'NONE'].\n" " :type subtype: string\n" BPY_PROPDEF_UPDATE_DOC ); diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index 170eeb9e2af..68b6baadd71 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -121,8 +121,7 @@ int pyrna_prop_validity_check(BPy_PropertyRNA *self) void pyrna_invalidate(BPy_DummyPointerRNA *self) { - self->ptr.type = NULL; /* this is checked for validity */ - self->ptr.id.data = NULL; /* should not be needed but prevent bad pointer access, just in case */ + RNA_POINTER_INVALIDATE(&self->ptr); } #ifdef USE_PYRNA_INVALIDATE_GC @@ -832,7 +831,7 @@ static PyObject *pyrna_struct_str(BPy_StructRNA *self) const char *name; if (!PYRNA_STRUCT_IS_VALID(self)) { - return PyUnicode_FromFormat("<bpy_struct, %.200s dead>", + return PyUnicode_FromFormat("<bpy_struct, %.200s invalid>", Py_TYPE(self)->tp_name); } @@ -1776,10 +1775,21 @@ static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyOb if (data) { if (flag & PROP_RNAPTR) { - if (value == Py_None) - memset(data, 0, sizeof(PointerRNA)); - else - *((PointerRNA *)data) = param->ptr; + if (flag & PROP_THICK_WRAP) { + if (value == Py_None) + memset(data, 0, sizeof(PointerRNA)); + else + *((PointerRNA *)data) = param->ptr; + } + else { + /* for function calls, we sometimes want to pass the 'ptr' directly, + * watch out that it remains valid!, possibly we could support this later if needed */ + BLI_assert(value_new == NULL); + if (value == Py_None) + *((void **)data) = NULL; + else + *((PointerRNA **)data) = ¶m->ptr; + } } else if (value == Py_None) { *((void **)data) = NULL; @@ -3866,6 +3876,12 @@ static PyObject *pyrna_prop_collection_idprop_add(BPy_PropertyRNA *self) { PointerRNA r_ptr; +#ifdef USE_PEDANTIC_WRITE + if (rna_disallow_writes && rna_id_write_error(&self->ptr, NULL)) { + return NULL; + } +#endif /* USE_PEDANTIC_WRITE */ + RNA_property_collection_add(&self->ptr, self->prop, &r_ptr); if (!r_ptr.data) { PyErr_SetString(PyExc_TypeError, "bpy_prop_collection.add(): not supported for this collection"); @@ -3880,6 +3896,12 @@ static PyObject *pyrna_prop_collection_idprop_remove(BPy_PropertyRNA *self, PyOb { int key = PyLong_AsLong(value); +#ifdef USE_PEDANTIC_WRITE + if (rna_disallow_writes && rna_id_write_error(&self->ptr, NULL)) { + return NULL; + } +#endif /* USE_PEDANTIC_WRITE */ + if (key == -1 && PyErr_Occurred()) { PyErr_SetString(PyExc_TypeError, "bpy_prop_collection.remove(): expected one int argument"); return NULL; @@ -3895,6 +3917,12 @@ static PyObject *pyrna_prop_collection_idprop_remove(BPy_PropertyRNA *self, PyOb static PyObject *pyrna_prop_collection_idprop_clear(BPy_PropertyRNA *self) { +#ifdef USE_PEDANTIC_WRITE + if (rna_disallow_writes && rna_id_write_error(&self->ptr, NULL)) { + return NULL; + } +#endif /* USE_PEDANTIC_WRITE */ + RNA_property_collection_clear(&self->ptr, self->prop); Py_RETURN_NONE; @@ -3904,6 +3932,12 @@ static PyObject *pyrna_prop_collection_idprop_move(BPy_PropertyRNA *self, PyObje { int key = 0, pos = 0; +#ifdef USE_PEDANTIC_WRITE + if (rna_disallow_writes && rna_id_write_error(&self->ptr, NULL)) { + return NULL; + } +#endif /* USE_PEDANTIC_WRITE */ + if (!PyArg_ParseTuple(args, "ii", &key, &pos)) { PyErr_SetString(PyExc_TypeError, "bpy_prop_collection.move(): expected two ints as arguments"); return NULL; @@ -6917,11 +6951,9 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param #ifdef USE_PEDANTIC_WRITE const int is_operator = RNA_struct_is_a(ptr->type, &RNA_Operator); - const char *func_id = RNA_function_identifier(func); + // const char *func_id = RNA_function_identifier(func); /* UNUSED */ /* testing, for correctness, not operator and not draw function */ - const short is_readonly = ((strncmp("draw", func_id, 4) == 0) || /* draw or draw_header */ - /*strstr("render", func_id) ||*/ - !is_operator); + const short is_readonly = !(RNA_function_flag(func) & FUNC_ALLOW_WRITE); #endif py_class = RNA_struct_py_type_get(ptr->type); diff --git a/source/blender/python/mathutils/mathutils_Matrix.c b/source/blender/python/mathutils/mathutils_Matrix.c index bb6a75c3346..ecc6437ceb5 100644 --- a/source/blender/python/mathutils/mathutils_Matrix.c +++ b/source/blender/python/mathutils/mathutils_Matrix.c @@ -384,13 +384,19 @@ static PyObject *Matrix_new(PyTypeObject *type, PyObject *args, PyObject *kwds) static PyObject *matrix__apply_to_copy(PyNoArgsFunction matrix_func, MatrixObject *self) { PyObject *ret = Matrix_copy(self); - PyObject *ret_dummy = matrix_func(ret); - if (ret_dummy) { - Py_DECREF(ret_dummy); - return (PyObject *)ret; + if (ret) { + PyObject *ret_dummy = matrix_func(ret); + if (ret_dummy) { + Py_DECREF(ret_dummy); + return (PyObject *)ret; + } + else { /* error */ + Py_DECREF(ret); + return NULL; + } } - else { /* error */ - Py_DECREF(ret); + else { + /* copy may fail if the read callback errors out */ return NULL; } } @@ -1196,17 +1202,27 @@ static PyObject *Matrix_invert(MatrixObject *self) if (det != 0) { /* calculate the classical adjoint */ - if (self->num_col == 2) { - mat[0] = MATRIX_ITEM(self, 1, 1); - mat[1] = -MATRIX_ITEM(self, 0, 1); - mat[2] = -MATRIX_ITEM(self, 1, 0); - mat[3] = MATRIX_ITEM(self, 0, 0); - } - else if (self->num_col == 3) { - adjoint_m3_m3((float (*)[3])mat, (float (*)[3])self->matrix); - } - else if (self->num_col == 4) { - adjoint_m4_m4((float (*)[4])mat, (float (*)[4])self->matrix); + switch (self->num_col) { + case 2: + { + adjoint_m2_m2((float (*)[2])mat, (float (*)[2])self->matrix); + break; + } + case 3: + { + adjoint_m3_m3((float (*)[3])mat, (float (*)[3])self->matrix); + break; + } + case 4: + { + adjoint_m4_m4((float (*)[4])mat, (float (*)[4])self->matrix); + break; + } + default: + PyErr_Format(PyExc_TypeError, + "Matrix invert(ed): size (%d) unsupported", + (int)self->num_col); + return NULL; } /* divide by determinate */ for (x = 0; x < (self->num_col * self->num_row); x++) { @@ -1236,7 +1252,7 @@ PyDoc_STRVAR(Matrix_inverted_doc, "\n" " Return an inverted copy of the matrix.\n" "\n" -" :return: the inverted matrix.\n" +" :return: the inverted matrix.\n" " :rtype: :class:`Matrix`\n" "\n" " .. note:: When the matrix cant be inverted a :exc:`ValueError` exception is raised.\n" @@ -1246,6 +1262,77 @@ static PyObject *Matrix_inverted(MatrixObject *self) return matrix__apply_to_copy((PyNoArgsFunction)Matrix_invert, self); } +/*---------------------------matrix.adjugate() ---------------------*/ +PyDoc_STRVAR(Matrix_adjugate_doc, +".. method:: adjugate()\n" +"\n" +" Set the matrix to its adjugate.\n" +"\n" +" .. note:: When the matrix cant be adjugated a :exc:`ValueError` exception is raised.\n" +"\n" +" .. seealso:: <http://en.wikipedia.org/wiki/Adjugate_matrix>\n" +); +static PyObject *Matrix_adjugate(MatrixObject *self) +{ + if (BaseMath_ReadCallback(self) == -1) + return NULL; + + if (self->num_col != self->num_row) { + PyErr_SetString(PyExc_TypeError, + "Matrix.adjugate(d): " + "only square matrices are supported"); + return NULL; + } + + /* calculate the classical adjoint */ + switch (self->num_col) { + case 2: + { + float mat[2][2]; + adjoint_m2_m2(mat, (float (*)[2])self->matrix); + copy_v4_v4((float *)self->matrix, (float *)mat); + break; + } + case 3: + { + float mat[3][3]; + adjoint_m3_m3(mat, (float (*)[3])self->matrix); + copy_m3_m3((float (*)[3])self->matrix, mat); + break; + } + case 4: + { + float mat[4][4]; + adjoint_m4_m4(mat, (float (*)[4])self->matrix); + copy_m4_m4((float (*)[4])self->matrix, mat); + break; + } + default: + PyErr_Format(PyExc_TypeError, + "Matrix adjugate(d): size (%d) unsupported", + (int)self->num_col); + return NULL; + } + + (void)BaseMath_WriteCallback(self); + Py_RETURN_NONE; +} + +PyDoc_STRVAR(Matrix_adjugated_doc, +".. method:: adjugated()\n" +"\n" +" Return an adjugated copy of the matrix.\n" +"\n" +" :return: the adjugated matrix.\n" +" :rtype: :class:`Matrix`\n" +"\n" +" .. note:: When the matrix cant be adjugated a :exc:`ValueError` exception is raised.\n" +); +static PyObject *Matrix_adjugated(MatrixObject *self) +{ + return matrix__apply_to_copy((PyNoArgsFunction)Matrix_adjugate, self); +} + PyDoc_STRVAR(Matrix_rotate_doc, ".. method:: rotate(other)\n" "\n" @@ -2281,6 +2368,8 @@ static struct PyMethodDef Matrix_methods[] = { {"transposed", (PyCFunction) Matrix_transposed, METH_NOARGS, Matrix_transposed_doc}, {"invert", (PyCFunction) Matrix_invert, METH_NOARGS, Matrix_invert_doc}, {"inverted", (PyCFunction) Matrix_inverted, METH_NOARGS, Matrix_inverted_doc}, + {"adjugate", (PyCFunction) Matrix_adjugate, METH_NOARGS, Matrix_adjugate_doc}, + {"adjugated", (PyCFunction) Matrix_adjugated, METH_NOARGS, Matrix_adjugated_doc}, {"to_3x3", (PyCFunction) Matrix_to_3x3, METH_NOARGS, Matrix_to_3x3_doc}, /* TODO. {"resize_3x3", (PyCFunction) Matrix_resize3x3, METH_NOARGS, Matrix_resize3x3_doc}, */ {"to_4x4", (PyCFunction) Matrix_to_4x4, METH_NOARGS, Matrix_to_4x4_doc}, diff --git a/source/blender/quicktime/apple/qtkit_export.m b/source/blender/quicktime/apple/qtkit_export.m index bf37faa07ff..e0858cd5ec2 100644 --- a/source/blender/quicktime/apple/qtkit_export.m +++ b/source/blender/quicktime/apple/qtkit_export.m @@ -561,19 +561,21 @@ int start_qt(struct Scene *scene, struct RenderData *rd, int rectx, int recty, R /* specifying the codec attributes : try to retrieve them from render data first*/ if (rd->qtcodecsettings.codecType) { - qtexport->frameAttributes = [NSDictionary dictionaryWithObjectsAndKeys: - stringWithCodecType(rd->qtcodecsettings.codecType), - QTAddImageCodecType, - [NSNumber numberWithLong:((rd->qtcodecsettings.codecSpatialQuality)*codecLosslessQuality)/100], - QTAddImageCodecQuality, - nil]; + qtexport->frameAttributes = [ + NSDictionary dictionaryWithObjectsAndKeys: + stringWithCodecType(rd->qtcodecsettings.codecType), + QTAddImageCodecType, + [NSNumber numberWithLong:((rd->qtcodecsettings.codecSpatialQuality)*codecLosslessQuality)/100], + QTAddImageCodecQuality, + nil]; } else { - qtexport->frameAttributes = [NSDictionary dictionaryWithObjectsAndKeys:@"jpeg", - QTAddImageCodecType, - [NSNumber numberWithLong:codecHighQuality], - QTAddImageCodecQuality, - nil]; + qtexport->frameAttributes = [ + NSDictionary dictionaryWithObjectsAndKeys:@"jpeg", + QTAddImageCodecType, + [NSNumber numberWithLong:codecHighQuality], + QTAddImageCodecQuality, + nil]; } [qtexport->frameAttributes retain]; diff --git a/source/blender/quicktime/apple/qtkit_import.m b/source/blender/quicktime/apple/qtkit_import.m index d7c8889b44a..2e910e38871 100644 --- a/source/blender/quicktime/apple/qtkit_import.m +++ b/source/blender/quicktime/apple/qtkit_import.m @@ -71,7 +71,7 @@ void quicktime_init(void) void quicktime_exit(void) { - if(G.have_quicktime) { + if (G.have_quicktime) { free_qtcomponentdata(); } } @@ -82,27 +82,30 @@ int anim_is_quicktime (const char *name) NSAutoreleasePool *pool; // don't let quicktime movie import handle these - if( BLI_testextensie(name, ".swf") || - BLI_testextensie(name, ".txt") || - BLI_testextensie(name, ".mpg") || - BLI_testextensie(name, ".avi") || // wouldn't be appropriate ;) - BLI_testextensie(name, ".mov") || // disabled, suboptimal decoding speed - BLI_testextensie(name, ".mp4") || // disabled, suboptimal decoding speed - BLI_testextensie(name, ".m4v") || // disabled, suboptimal decoding speed - BLI_testextensie(name, ".tga") || - BLI_testextensie(name, ".png") || - BLI_testextensie(name, ".bmp") || - BLI_testextensie(name, ".jpg") || - BLI_testextensie(name, ".wav") || - BLI_testextensie(name, ".zip") || - BLI_testextensie(name, ".mp3")) return 0; + if (BLI_testextensie(name, ".swf") || + BLI_testextensie(name, ".txt") || + BLI_testextensie(name, ".mpg") || + BLI_testextensie(name, ".avi") || // wouldn't be appropriate ;) + BLI_testextensie(name, ".mov") || // disabled, suboptimal decoding speed + BLI_testextensie(name, ".mp4") || // disabled, suboptimal decoding speed + BLI_testextensie(name, ".m4v") || // disabled, suboptimal decoding speed + BLI_testextensie(name, ".tga") || + BLI_testextensie(name, ".png") || + BLI_testextensie(name, ".bmp") || + BLI_testextensie(name, ".jpg") || + BLI_testextensie(name, ".wav") || + BLI_testextensie(name, ".zip") || + BLI_testextensie(name, ".mp3")) + { + return 0; + } - if(QTIME_DEBUG) printf("qt: checking as movie: %s\n", name); + if (QTIME_DEBUG) printf("qt: checking as movie: %s\n", name); pool = [[NSAutoreleasePool alloc] init]; - if([QTMovie canInitWithFile:[NSString stringWithCString:name - encoding:[NSString defaultCStringEncoding]]]) + if ([QTMovie canInitWithFile:[NSString stringWithCString:name + encoding:[NSString defaultCStringEncoding]]]) { [pool drain]; return true; diff --git a/source/blender/render/extern/include/RE_engine.h b/source/blender/render/extern/include/RE_engine.h index 2376aeca55e..20024eab633 100644 --- a/source/blender/render/extern/include/RE_engine.h +++ b/source/blender/render/extern/include/RE_engine.h @@ -35,6 +35,8 @@ #include "DNA_listBase.h" #include "RNA_types.h" +struct bNode; +struct bNodeTree; struct Object; struct Render; struct RenderEngine; @@ -75,6 +77,8 @@ typedef struct RenderEngineType { void (*view_update)(struct RenderEngine *engine, const struct bContext *context); void (*view_draw)(struct RenderEngine *engine, const struct bContext *context); + void (*update_script_node)(struct RenderEngine *engine, struct bNodeTree *ntree, struct bNode *node); + /* RNA integration */ ExtensionRNA ext; } RenderEngineType; @@ -94,6 +98,8 @@ typedef struct RenderEngine { char *text; int resolution_x, resolution_y; + + struct ReportList *reports; } RenderEngine; RenderEngine *RE_engine_create(RenderEngineType *type); diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index 4aa30e6c4cf..4746e0f6b08 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -1526,9 +1526,12 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem int i, a, k, max_k=0, totpart, do_simplify = FALSE, do_surfacecache = FALSE, use_duplimat = FALSE; int totchild=0; int seed, path_nbr=0, orco1=0, num; - int totface, *origindex = 0; + int totface; char **uv_name=0; + const int *index_mf_to_mpoly = NULL; + const int *index_mp_to_orig = NULL; + /* 1. check that everything is ok & updated */ if (psys==NULL) return 0; @@ -1698,9 +1701,13 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem do_surfacecache = TRUE; totface= psmd->dm->getNumTessFaces(psmd->dm); - origindex= psmd->dm->getTessFaceDataArray(psmd->dm, CD_ORIGINDEX); + index_mf_to_mpoly = psmd->dm->getTessFaceDataArray(psmd->dm, CD_ORIGINDEX); + index_mp_to_orig = psmd->dm->getPolyDataArray(psmd->dm, CD_ORIGINDEX); + if ((index_mf_to_mpoly && index_mp_to_orig) == FALSE) { + index_mf_to_mpoly = index_mp_to_orig = NULL; + } for (a=0; a<totface; a++) - strandbuf->totbound= MAX2(strandbuf->totbound, (origindex)? origindex[a]: a); + strandbuf->totbound = max_ii(strandbuf->totbound, (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, a): a); strandbuf->totbound++; strandbuf->bound= MEM_callocN(sizeof(StrandBound)*strandbuf->totbound, "StrandBound"); @@ -1811,7 +1818,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem do_simplify = psys_render_simplify_params(psys, cpa, simplify); if (strandbuf) { - int orignum= (origindex)? origindex[cpa->num]: cpa->num; + int orignum = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, cpa->num) : cpa->num; if (orignum > sbound - strandbuf->bound) { sbound= strandbuf->bound + orignum; diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c index 94146467145..076cad05c84 100644 --- a/source/blender/render/intern/source/external_engine.c +++ b/source/blender/render/intern/source/external_engine.c @@ -64,7 +64,7 @@ static RenderEngineType internal_render_type = { NULL, NULL, "BLENDER_RENDER", N_("Blender Render"), RE_INTERNAL, - NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, {NULL, NULL, NULL} }; @@ -73,7 +73,7 @@ static RenderEngineType internal_render_type = { static RenderEngineType internal_game_type = { NULL, NULL, "BLENDER_GAME", N_("Blender Game"), RE_INTERNAL | RE_GAME, - NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, {NULL, NULL, NULL} }; @@ -292,7 +292,12 @@ void RE_engine_update_progress(RenderEngine *engine, float progress) void RE_engine_report(RenderEngine *engine, int type, const char *msg) { - BKE_report(engine->re->reports, type, msg); + Render *re = engine->re; + + if (re) + BKE_report(engine->re->reports, type, msg); + else if(engine->reports) + BKE_report(engine->reports, type, msg); } /* Render */ diff --git a/source/blender/render/intern/source/imagetexture.c b/source/blender/render/intern/source/imagetexture.c index 44faee73d35..db1454fd82f 100644 --- a/source/blender/render/intern/source/imagetexture.c +++ b/source/blender/render/intern/source/imagetexture.c @@ -764,39 +764,39 @@ static void area_sample(TexResult *texr, ImBuf *ibuf, float fx, float fy, afdata /* table of (exp(ar) - exp(a)) / (1 - exp(a)) for r in range [0, 1] and a = -2 * used instead of actual gaussian, otherwise at high texture magnifications circular artifacts are visible */ #define EWA_MAXIDX 255 -static float EWA_WTS[EWA_MAXIDX + 1] = -{ 1.f, 0.990965f, 0.982f, 0.973105f, 0.96428f, 0.955524f, 0.946836f, 0.938216f, 0.929664f, - 0.921178f, 0.912759f, 0.904405f, 0.896117f, 0.887893f, 0.879734f, 0.871638f, 0.863605f, - 0.855636f, 0.847728f, 0.839883f, 0.832098f, 0.824375f, 0.816712f, 0.809108f, 0.801564f, - 0.794079f, 0.786653f, 0.779284f, 0.771974f, 0.76472f, 0.757523f, 0.750382f, 0.743297f, - 0.736267f, 0.729292f, 0.722372f, 0.715505f, 0.708693f, 0.701933f, 0.695227f, 0.688572f, - 0.68197f, 0.67542f, 0.66892f, 0.662471f, 0.656073f, 0.649725f, 0.643426f, 0.637176f, - 0.630976f, 0.624824f, 0.618719f, 0.612663f, 0.606654f, 0.600691f, 0.594776f, 0.588906f, - 0.583083f, 0.577305f, 0.571572f, 0.565883f, 0.56024f, 0.55464f, 0.549084f, 0.543572f, - 0.538102f, 0.532676f, 0.527291f, 0.521949f, 0.516649f, 0.511389f, 0.506171f, 0.500994f, - 0.495857f, 0.490761f, 0.485704f, 0.480687f, 0.475709f, 0.470769f, 0.465869f, 0.461006f, - 0.456182f, 0.451395f, 0.446646f, 0.441934f, 0.437258f, 0.432619f, 0.428017f, 0.42345f, - 0.418919f, 0.414424f, 0.409963f, 0.405538f, 0.401147f, 0.39679f, 0.392467f, 0.388178f, - 0.383923f, 0.379701f, 0.375511f, 0.371355f, 0.367231f, 0.363139f, 0.359079f, 0.355051f, - 0.351055f, 0.347089f, 0.343155f, 0.339251f, 0.335378f, 0.331535f, 0.327722f, 0.323939f, - 0.320186f, 0.316461f, 0.312766f, 0.3091f, 0.305462f, 0.301853f, 0.298272f, 0.294719f, - 0.291194f, 0.287696f, 0.284226f, 0.280782f, 0.277366f, 0.273976f, 0.270613f, 0.267276f, - 0.263965f, 0.26068f, 0.257421f, 0.254187f, 0.250979f, 0.247795f, 0.244636f, 0.241502f, - 0.238393f, 0.235308f, 0.232246f, 0.229209f, 0.226196f, 0.223206f, 0.220239f, 0.217296f, - 0.214375f, 0.211478f, 0.208603f, 0.20575f, 0.20292f, 0.200112f, 0.197326f, 0.194562f, - 0.191819f, 0.189097f, 0.186397f, 0.183718f, 0.18106f, 0.178423f, 0.175806f, 0.17321f, - 0.170634f, 0.168078f, 0.165542f, 0.163026f, 0.16053f, 0.158053f, 0.155595f, 0.153157f, - 0.150738f, 0.148337f, 0.145955f, 0.143592f, 0.141248f, 0.138921f, 0.136613f, 0.134323f, - 0.132051f, 0.129797f, 0.12756f, 0.125341f, 0.123139f, 0.120954f, 0.118786f, 0.116635f, - 0.114501f, 0.112384f, 0.110283f, 0.108199f, 0.106131f, 0.104079f, 0.102043f, 0.100023f, - 0.0980186f, 0.09603f, 0.094057f, 0.0920994f, 0.0901571f, 0.08823f, 0.0863179f, 0.0844208f, - 0.0825384f, 0.0806708f, 0.0788178f, 0.0769792f, 0.0751551f, 0.0733451f, 0.0715493f, 0.0697676f, - 0.0679997f, 0.0662457f, 0.0645054f, 0.0627786f, 0.0610654f, 0.0593655f, 0.0576789f, 0.0560055f, - 0.0543452f, 0.0526979f, 0.0510634f, 0.0494416f, 0.0478326f, 0.0462361f, 0.0446521f, 0.0430805f, - 0.0415211f, 0.039974f, 0.0384389f, 0.0369158f, 0.0354046f, 0.0339052f, 0.0324175f, 0.0309415f, - 0.029477f, 0.0280239f, 0.0265822f, 0.0251517f, 0.0237324f, 0.0223242f, 0.020927f, 0.0195408f, - 0.0181653f, 0.0168006f, 0.0154466f, 0.0141031f, 0.0127701f, 0.0114476f, 0.0101354f, 0.00883339f, - 0.00754159f, 0.00625989f, 0.00498819f, 0.00372644f, 0.00247454f, 0.00123242f, 0.f +static float EWA_WTS[EWA_MAXIDX + 1] = { + 1.f, 0.990965f, 0.982f, 0.973105f, 0.96428f, 0.955524f, 0.946836f, 0.938216f, 0.929664f, + 0.921178f, 0.912759f, 0.904405f, 0.896117f, 0.887893f, 0.879734f, 0.871638f, 0.863605f, + 0.855636f, 0.847728f, 0.839883f, 0.832098f, 0.824375f, 0.816712f, 0.809108f, 0.801564f, + 0.794079f, 0.786653f, 0.779284f, 0.771974f, 0.76472f, 0.757523f, 0.750382f, 0.743297f, + 0.736267f, 0.729292f, 0.722372f, 0.715505f, 0.708693f, 0.701933f, 0.695227f, 0.688572f, + 0.68197f, 0.67542f, 0.66892f, 0.662471f, 0.656073f, 0.649725f, 0.643426f, 0.637176f, + 0.630976f, 0.624824f, 0.618719f, 0.612663f, 0.606654f, 0.600691f, 0.594776f, 0.588906f, + 0.583083f, 0.577305f, 0.571572f, 0.565883f, 0.56024f, 0.55464f, 0.549084f, 0.543572f, + 0.538102f, 0.532676f, 0.527291f, 0.521949f, 0.516649f, 0.511389f, 0.506171f, 0.500994f, + 0.495857f, 0.490761f, 0.485704f, 0.480687f, 0.475709f, 0.470769f, 0.465869f, 0.461006f, + 0.456182f, 0.451395f, 0.446646f, 0.441934f, 0.437258f, 0.432619f, 0.428017f, 0.42345f, + 0.418919f, 0.414424f, 0.409963f, 0.405538f, 0.401147f, 0.39679f, 0.392467f, 0.388178f, + 0.383923f, 0.379701f, 0.375511f, 0.371355f, 0.367231f, 0.363139f, 0.359079f, 0.355051f, + 0.351055f, 0.347089f, 0.343155f, 0.339251f, 0.335378f, 0.331535f, 0.327722f, 0.323939f, + 0.320186f, 0.316461f, 0.312766f, 0.3091f, 0.305462f, 0.301853f, 0.298272f, 0.294719f, + 0.291194f, 0.287696f, 0.284226f, 0.280782f, 0.277366f, 0.273976f, 0.270613f, 0.267276f, + 0.263965f, 0.26068f, 0.257421f, 0.254187f, 0.250979f, 0.247795f, 0.244636f, 0.241502f, + 0.238393f, 0.235308f, 0.232246f, 0.229209f, 0.226196f, 0.223206f, 0.220239f, 0.217296f, + 0.214375f, 0.211478f, 0.208603f, 0.20575f, 0.20292f, 0.200112f, 0.197326f, 0.194562f, + 0.191819f, 0.189097f, 0.186397f, 0.183718f, 0.18106f, 0.178423f, 0.175806f, 0.17321f, + 0.170634f, 0.168078f, 0.165542f, 0.163026f, 0.16053f, 0.158053f, 0.155595f, 0.153157f, + 0.150738f, 0.148337f, 0.145955f, 0.143592f, 0.141248f, 0.138921f, 0.136613f, 0.134323f, + 0.132051f, 0.129797f, 0.12756f, 0.125341f, 0.123139f, 0.120954f, 0.118786f, 0.116635f, + 0.114501f, 0.112384f, 0.110283f, 0.108199f, 0.106131f, 0.104079f, 0.102043f, 0.100023f, + 0.0980186f, 0.09603f, 0.094057f, 0.0920994f, 0.0901571f, 0.08823f, 0.0863179f, 0.0844208f, + 0.0825384f, 0.0806708f, 0.0788178f, 0.0769792f, 0.0751551f, 0.0733451f, 0.0715493f, 0.0697676f, + 0.0679997f, 0.0662457f, 0.0645054f, 0.0627786f, 0.0610654f, 0.0593655f, 0.0576789f, 0.0560055f, + 0.0543452f, 0.0526979f, 0.0510634f, 0.0494416f, 0.0478326f, 0.0462361f, 0.0446521f, 0.0430805f, + 0.0415211f, 0.039974f, 0.0384389f, 0.0369158f, 0.0354046f, 0.0339052f, 0.0324175f, 0.0309415f, + 0.029477f, 0.0280239f, 0.0265822f, 0.0251517f, 0.0237324f, 0.0223242f, 0.020927f, 0.0195408f, + 0.0181653f, 0.0168006f, 0.0154466f, 0.0141031f, 0.0127701f, 0.0114476f, 0.0101354f, 0.00883339f, + 0.00754159f, 0.00625989f, 0.00498819f, 0.00372644f, 0.00247454f, 0.00123242f, 0.f }; /* test if a float value is 'nan' diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c index 217fcc3c4ac..9fe2620747c 100644 --- a/source/blender/render/intern/source/rendercore.c +++ b/source/blender/render/intern/source/rendercore.c @@ -2376,10 +2376,28 @@ static void do_bake_shade(void *handle, int x, int y, float u, float v) v2= vlr->v2->co; v3= vlr->v3->co; } - - /* renderco */ + l= 1.0f-u-v; + + /* shrink barycentric coordinates inwards slightly to avoid some issues + * where baking selected to active might just miss the other face at the + * near the edge of a face */ + if (bs->actob) { + const float eps = 1.0f - 1e-4f; + float invsum; + + u = (u - 0.5f)*eps + 0.5f; + v = (v - 0.5f)*eps + 0.5f; + l = (l - 0.5f)*eps + 0.5f; + + invsum = 1.0f/(u + v + l); + + u *= invsum; + v *= invsum; + l *= invsum; + } + /* renderco */ shi->co[0]= l*v3[0]+u*v1[0]+v*v2[0]; shi->co[1]= l*v3[1]+u*v1[1]+v*v2[1]; shi->co[2]= l*v3[2]+u*v1[2]+v*v2[2]; diff --git a/source/blender/render/intern/source/strand.c b/source/blender/render/intern/source/strand.c index 6e2e97b95de..2fe8adaa1ee 100644 --- a/source/blender/render/intern/source/strand.c +++ b/source/blender/render/intern/source/strand.c @@ -449,6 +449,7 @@ typedef struct StrandPart { int sample; int shadow; float (*jit)[2]; + int samples; StrandSegment *segment; float t[3], s[3]; @@ -669,12 +670,8 @@ static void strand_render(Render *re, StrandSegment *sseg, float winmat[][4], St float dt= p2->t - p1->t; int a; - if (re->osa) { - for (a=0; a<re->osa; a++) - do_scanconvert_strand(re, spart, zspan, t, dt, p1->zco2, p1->zco1, p2->zco1, p2->zco2, a); - } - else - do_scanconvert_strand(re, spart, zspan, t, dt, p1->zco2, p1->zco1, p2->zco1, p2->zco2, 0); + for (a=0; a<spart->samples; a++) + do_scanconvert_strand(re, spart, zspan, t, dt, p1->zco2, p1->zco1, p2->zco1, p2->zco2, a); } else { float hoco1[4], hoco2[4]; @@ -786,7 +783,7 @@ void render_strand_segment(Render *re, float winmat[][4], StrandPart *spart, ZSp } /* render call to fill in strands */ -int zbuffer_strands_abuf(Render *re, RenderPart *pa, APixstrand *apixbuf, ListBase *apsmbase, unsigned int lay, int UNUSED(negzmask), float winmat[][4], int winx, int winy, int UNUSED(sample), float (*jit)[2], float clipcrop, int shadow, StrandShadeCache *cache) +int zbuffer_strands_abuf(Render *re, RenderPart *pa, APixstrand *apixbuf, ListBase *apsmbase, unsigned int lay, int UNUSED(negzmask), float winmat[][4], int winx, int winy, int samples, float (*jit)[2], float clipcrop, int shadow, StrandShadeCache *cache) { ObjectRen *obr; ObjectInstanceRen *obi; @@ -820,6 +817,7 @@ int zbuffer_strands_abuf(Render *re, RenderPart *pa, APixstrand *apixbuf, ListBa spart.cache= cache; spart.shadow= shadow; spart.jit= jit; + spart.samples= samples; zbuf_alloc_span(&zspan, pa->rectx, pa->recty, clipcrop); diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index e7b7f679ce3..b9a4e720230 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -214,6 +214,7 @@ int WM_operator_call_py(struct bContext *C, struct wmOperatorType *ot, short c void WM_operator_properties_alloc(struct PointerRNA **ptr, struct IDProperty **properties, const char *opstring); /* used for keymap and macro items */ void WM_operator_properties_sanitize(struct PointerRNA *ptr, const short no_context); /* make props context sensitive or not */ +int WM_operator_properties_default(struct PointerRNA *ptr, const int do_update); void WM_operator_properties_reset(struct wmOperator *op); void WM_operator_properties_create(struct PointerRNA *ptr, const char *opstring); void WM_operator_properties_create_ptr(struct PointerRNA *ptr, struct wmOperatorType *ot); @@ -357,8 +358,9 @@ void WM_jobs_callbacks(struct wmJob *, void WM_jobs_start(struct wmWindowManager *wm, struct wmJob *); void WM_jobs_stop(struct wmWindowManager *wm, void *owner, void *startjob); void WM_jobs_kill(struct wmWindowManager *wm, void *owner, void (*)(void *, short int *, short int *, float *)); -void WM_jobs_stop_all(struct wmWindowManager *wm); - +void WM_jobs_kill_all(struct wmWindowManager *wm); + void WM_jobs_kill_all_except(struct wmWindowManager *wm, void *owner); + int WM_jobs_has_running(struct wmWindowManager *wm); /* clipboard */ diff --git a/source/blender/windowmanager/WM_keymap.h b/source/blender/windowmanager/WM_keymap.h index 5c88babfb47..43369154dbb 100644 --- a/source/blender/windowmanager/WM_keymap.h +++ b/source/blender/windowmanager/WM_keymap.h @@ -43,7 +43,7 @@ struct EnumPropertyItem; wmKeyConfig *WM_keyconfig_new (struct wmWindowManager *wm, const char *idname); wmKeyConfig *WM_keyconfig_new_user(struct wmWindowManager *wm, const char *idname); -void WM_keyconfig_remove (struct wmWindowManager *wm, struct wmKeyConfig *keyconf); +int WM_keyconfig_remove (struct wmWindowManager *wm, struct wmKeyConfig *keyconf); void WM_keyconfig_free (struct wmKeyConfig *keyconf); void WM_keyconfig_set_active(struct wmWindowManager *wm, const char *idname); @@ -63,8 +63,8 @@ wmKeyMapItem *WM_keymap_add_item(struct wmKeyMap *keymap, const char *idname, in wmKeyMapItem *WM_keymap_add_menu(struct wmKeyMap *keymap, const char *idname, int type, int val, int modifier, int keymodifier); -void WM_keymap_remove_item(struct wmKeyMap *keymap, struct wmKeyMapItem *kmi); -char *WM_keymap_item_to_string(wmKeyMapItem *kmi, char *str, int len); +int WM_keymap_remove_item(struct wmKeyMap *keymap, struct wmKeyMapItem *kmi); +char *WM_keymap_item_to_string(wmKeyMapItem *kmi, char *str, int len); wmKeyMap *WM_keymap_list_find(ListBase *lb, const char *idname, int spaceid, int regionid); wmKeyMap *WM_keymap_find(struct wmKeyConfig *keyconf, const char *idname, int spaceid, int regionid); diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h index d1c08f43d07..4dbb3a85425 100644 --- a/source/blender/windowmanager/WM_types.h +++ b/source/blender/windowmanager/WM_types.h @@ -556,8 +556,8 @@ typedef struct wmOperatorType { /* previous settings - for initializing on re-use */ struct IDProperty *last_properties; - /* rna property to use for generic invoke functions. - * menus, enum search... etc */ + /* Default rna property to use for generic invoke functions. + * menus, enum search... etc. Example: Enum 'type' for a Delete menu */ PropertyRNA *prop; /* struct wmOperatorTypeMacro */ diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 9e072c4b03a..fee94b95a6a 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -452,10 +452,10 @@ void WM_event_print(wmEvent *event) RNA_enum_identifier(event_type_items, event->type, &type_id); RNA_enum_identifier(event_value_items, event->val, &val_id); - printf("wmEvent - type:%d/%s, val:%d/%s, " - "shift:%d, ctrl:%d, alt:%d, oskey:%d, keymodifier:%d, " - "mouse:(%d,%d), ascii:'%c', utf8:'%.*s', " - "keymap_idname:%s, pointer:%p\n", + printf("wmEvent type:%d / %s, val:%d / %s, \n" + " shift:%d, ctrl:%d, alt:%d, oskey:%d, keymodifier:%d, \n" + " mouse:(%d,%d), ascii:'%c', utf8:'%.*s', " + " keymap_idname:%s, pointer:%p\n", event->type, type_id, event->val, val_id, event->shift, event->ctrl, event->alt, event->oskey, event->keymodifier, event->x, event->y, event->ascii, @@ -1281,25 +1281,50 @@ int WM_userdef_event_map(int kmitype) static void wm_eventemulation(wmEvent *event) { + /* Store last mmb event value to make emulation work when modifier keys are released first. */ static int mmb_emulated = 0; /* this should be in a data structure somwhere */ /* middlemouse emulation */ if (U.flag & USER_TWOBUTTONMOUSE) { - if (event->type == LEFTMOUSE && (event->alt || mmb_emulated == KM_PRESS)) { - event->type = MIDDLEMOUSE; - event->alt = 0; - mmb_emulated = event->val; + if (event->type == LEFTMOUSE) { + + if (event->val == KM_PRESS && event->alt) { + event->type = MIDDLEMOUSE; + event->alt = 0; + mmb_emulated = 1; + } + else if (event->val == KM_RELEASE) { + /* only send middle-mouse release if emulated */ + if (mmb_emulated) { + event->type = MIDDLEMOUSE; + event->alt = 0; + } + mmb_emulated = 0; + } } + } #ifdef __APPLE__ + /* rightmouse emulation */ if (U.flag & USER_TWOBUTTONMOUSE) { - if (event->type == LEFTMOUSE && (event->oskey || mmb_emulated == KM_PRESS)) { - event->type = RIGHTMOUSE; - event->oskey = 0; - mmb_emulated = event->val; + if (event->type == LEFTMOUSE) { + + if (event->val == KM_PRESS && event->oskey) { + event->type = RIGHTMOUSE; + event->oskey = 0; + mmb_emulated = 1; + } + else if (event->val == KM_RELEASE) { + if (mmb_emulated) { + event->oskey = RIGHTMOUSE; + event->alt = 0; + } + mmb_emulated = 0; + } } + } #endif @@ -1331,7 +1356,12 @@ static int wm_eventmatch(wmEvent *winevent, wmKeyMapItem *kmi) /* the matching rules */ if (kmitype == KM_TEXTINPUT) - if (ISTEXTINPUT(winevent->type) && (winevent->ascii || winevent->utf8_buf[0])) return 1; + if (winevent->val == KM_PRESS) { // prevent double clicks + /* NOT using ISTEXTINPUT anymore because (at least on Windows) some key codes above 255 + could have printable ascii keys - BUG [#30479] */ + if (ISKEYBOARD(winevent->type) && (winevent->ascii || winevent->utf8_buf[0])) return 1; + } + if (kmitype != KM_ANY) if (winevent->type != kmitype) return 0; @@ -1348,14 +1378,8 @@ static int wm_eventmatch(wmEvent *winevent, wmKeyMapItem *kmi) if (kmi->oskey != KM_ANY) if (winevent->oskey != kmi->oskey && !(winevent->oskey & kmi->oskey)) return 0; - if (kmi->keymodifier) - if (winevent->keymodifier != kmi->keymodifier) return 0; + if (winevent->keymodifier != kmi->keymodifier) return 0; - /* key modifiers always check when event has it */ - /* otherwise regular keypresses with keymodifier still work */ - if (winevent->keymodifier) - if (ISTEXTINPUT(winevent->type)) - if (winevent->keymodifier != kmi->keymodifier) return 0; return 1; } @@ -1571,72 +1595,55 @@ static int wm_handler_fileselect_call(bContext *C, ListBase *handlers, wmEventHa /* needed for uiPupMenuReports */ if (event->val == EVT_FILESELECT_EXEC) { -#if 0 // use REDALERT now + int retval; - /* a bit weak, might become arg for WM_event_fileselect? */ - /* XXX also extension code in image-save doesnt work for this yet */ - if (RNA_struct_find_property(handler->op->ptr, "check_existing") && - RNA_boolean_get(handler->op->ptr, "check_existing")) - { - char *path = RNA_string_get_alloc(handler->op->ptr, "filepath", NULL, 0); - /* this gives ownership to pupmenu */ - uiPupMenuSaveOver(C, handler->op, (path) ? path : ""); - if (path) - MEM_freeN(path); - } - else -#endif - { - int retval; - - if (handler->op->type->flag & OPTYPE_UNDO) - wm->op_undo_depth++; - - retval = handler->op->type->exec(C, handler->op); + if (handler->op->type->flag & OPTYPE_UNDO) + wm->op_undo_depth++; - /* XXX check this carefully, CTX_wm_manager(C) == wm is a bit hackish */ - if (handler->op->type->flag & OPTYPE_UNDO && CTX_wm_manager(C) == wm) - wm->op_undo_depth--; + retval = handler->op->type->exec(C, handler->op); + + /* XXX check this carefully, CTX_wm_manager(C) == wm is a bit hackish */ + if (handler->op->type->flag & OPTYPE_UNDO && CTX_wm_manager(C) == wm) + wm->op_undo_depth--; - if (retval & OPERATOR_FINISHED) - if (G.debug & G_DEBUG_WM) - wm_operator_print(C, handler->op); + if (retval & OPERATOR_FINISHED) + if (G.debug & G_DEBUG_WM) + wm_operator_print(C, handler->op); - /* XXX check this carefully, CTX_wm_manager(C) == wm is a bit hackish */ - if (CTX_wm_manager(C) == wm && wm->op_undo_depth == 0) - if (handler->op->type->flag & OPTYPE_UNDO) - ED_undo_push_op(C, handler->op); + /* XXX check this carefully, CTX_wm_manager(C) == wm is a bit hackish */ + if (CTX_wm_manager(C) == wm && wm->op_undo_depth == 0) + if (handler->op->type->flag & OPTYPE_UNDO) + ED_undo_push_op(C, handler->op); - if (handler->op->reports->list.first) { + if (handler->op->reports->list.first) { - /* FIXME, temp setting window, this is really bad! + /* FIXME, temp setting window, this is really bad! * only have because lib linking errors need to be seen by users :( * it can be removed without breaking anything but then no linking errors - campbell */ - wmWindow *win_prev = CTX_wm_window(C); - ScrArea *area_prev = CTX_wm_area(C); - ARegion *ar_prev = CTX_wm_region(C); - - if (win_prev == NULL) - CTX_wm_window_set(C, CTX_wm_manager(C)->windows.first); + wmWindow *win_prev = CTX_wm_window(C); + ScrArea *area_prev = CTX_wm_area(C); + ARegion *ar_prev = CTX_wm_region(C); - handler->op->reports->printlevel = RPT_WARNING; - uiPupMenuReports(C, handler->op->reports); + if (win_prev == NULL) + CTX_wm_window_set(C, CTX_wm_manager(C)->windows.first); - /* XXX - copied from 'wm_operator_finished()' */ - /* add reports to the global list, otherwise they are not seen */ - BLI_movelisttolist(&CTX_wm_reports(C)->list, &handler->op->reports->list); + handler->op->reports->printlevel = RPT_WARNING; + uiPupMenuReports(C, handler->op->reports); - CTX_wm_window_set(C, win_prev); - CTX_wm_area_set(C, area_prev); - CTX_wm_region_set(C, ar_prev); - } + /* XXX - copied from 'wm_operator_finished()' */ + /* add reports to the global list, otherwise they are not seen */ + BLI_movelisttolist(&CTX_wm_reports(C)->list, &handler->op->reports->list); - if (retval & OPERATOR_FINISHED) { - WM_operator_last_properties_store(handler->op); - } + CTX_wm_window_set(C, win_prev); + CTX_wm_area_set(C, area_prev); + CTX_wm_region_set(C, ar_prev); + } - WM_operator_free(handler->op); + if (retval & OPERATOR_FINISHED) { + WM_operator_last_properties_store(handler->op); } + + WM_operator_free(handler->op); } else { if (handler->op->type->cancel) { @@ -1712,13 +1719,6 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers return action; } -#ifndef NDEBUG - if (do_debug_handler) { - printf("%s: handling event\n", __func__); - WM_event_print(event); - } -#endif - /* modal handlers can get removed in this loop, we keep the loop this way * * note: check 'handlers->first' because in rare cases the handlers can be cleared @@ -1774,11 +1774,10 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers action |= wm_handler_operator_call(C, handlers, handler, event, kmi->ptr); if (action & WM_HANDLER_BREAK) { /* not always_pass here, it denotes removed handler */ -#ifndef NDEBUG - if (do_debug_handler) { - printf("%s: handled! '%s'...", __func__, kmi->idname); - } -#endif + + if (G.debug & (G_DEBUG_EVENTS | G_DEBUG_HANDLERS)) + printf("%s: handled! '%s'\n", __func__, kmi->idname); + break; } else { @@ -1881,14 +1880,18 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers) { int action = wm_handlers_do_intern(C, event, handlers); - if (!ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE) && !ISTIMER(event->type)) { - + /* fileread case */ + if (CTX_wm_window(C) == NULL) + return action; + + if (!ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE) && !ISTIMER(event->type)) { + /* test for CLICK events */ if (wm_action_not_handled(action)) { wmWindow *win = CTX_wm_window(C); /* eventstate stores if previous event was a KM_PRESS, in case that - wasn't handled, the KM_RELEASE will become a KM_CLICK */ + * wasn't handled, the KM_RELEASE will become a KM_CLICK */ if (win && event->val == KM_PRESS) { win->eventstate->check_click = TRUE; @@ -1898,7 +1901,11 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers) if (event->val == KM_RELEASE && win->eventstate->prevval == KM_PRESS && win->eventstate->check_click == TRUE) { event->val = KM_CLICK; - // printf("add KM_CLICK\n"); + + if (G.debug & (G_DEBUG_HANDLERS)) { + printf("%s: handling CLICK\n", __func__); + } + action |= wm_handlers_do_intern(C, event, handlers); event->val = KM_RELEASE; @@ -1917,7 +1924,7 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers) else { wmWindow *win = CTX_wm_window(C); - if(win) + if (win) win->eventstate->check_click = 0; } } @@ -2099,10 +2106,13 @@ void wm_event_do_handlers(bContext *C) while ( (event = win->queue.first) ) { int action = WM_HANDLER_CONTINUE; - if ((G.debug & G_DEBUG_HANDLERS) && event && !ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)) { - printf("%s: pass on evt %d val %d\n", __func__, event->type, event->val); +#ifdef DEBUG + if (G.debug & (G_DEBUG_HANDLERS | G_DEBUG_EVENTS) && !ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)) { + printf("\n%s: Handling event\n", __func__); + WM_event_print(event); } - +#endif + wm_eventemulation(event); CTX_wm_window_set(C, win); @@ -2746,8 +2756,6 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U update_tablet_data(win, &event); wm_event_add(win, &event); - - //printf("sending MOUSEMOVE %d %d\n", event.x, event.y); /* also add to other window if event is there, this makes overdraws disappear nicely */ /* it remaps mousecoord to other window in event */ @@ -2788,7 +2796,9 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U event.x = evt->x = cx; event.y = evt->y = (win->sizey - 1) - cy; } - + + event.val = 0; + /* Use prevx/prevy so we can calculate the delta later */ event.prevx = event.x - pd->deltaX; event.prevy = event.y - (-pd->deltaY); @@ -2803,10 +2813,6 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U { GHOST_TEventButtonData *bd = customdata; - /* copy prev state to event state */ - evt->prevval = evt->val; - evt->prevtype = evt->type; - /* get value and type from ghost */ event.val = (type == GHOST_kEventButtonDown) ? KM_PRESS : KM_RELEASE; @@ -2821,6 +2827,10 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U else event.type = MIDDLEMOUSE; + /* copy previous state to prev event state (two old!) */ + evt->prevval = evt->val; + evt->prevtype = evt->type; + /* copy to event state */ evt->val = event.val; evt->type = event.type; @@ -2841,10 +2851,12 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U (ABS(event.y - evt->prevclicky)) <= 2 && ((PIL_check_seconds_timer() - evt->prevclicktime) * 1000 < U.dbl_click_time)) { + if (G.debug & (G_DEBUG_HANDLERS | G_DEBUG_EVENTS) ) + printf("%s Send double click\n", __func__); event.val = KM_DBL_CLICK; } } - if (event.val == KM_RELEASE) { + if (event.val == KM_PRESS) { evt->prevclicktime = PIL_check_seconds_timer(); evt->prevclickx = event.x; evt->prevclicky = event.y; @@ -2880,7 +2892,7 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U memcpy(event.utf8_buf, kd->utf8_buf, sizeof(event.utf8_buf)); /* might be not null terminated*/ event.val = (type == GHOST_kEventKeyDown) ? KM_PRESS : KM_RELEASE; - /* copy prev state to event state */ + /* copy previous state to prev event state (two old!) */ evt->prevval = evt->val; evt->prevtype = evt->type; @@ -2945,23 +2957,23 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U } /* double click test */ - if (event.type == evt->prevtype && event.val == KM_PRESS) { + /* if previous event was same type, and previous was release, and now it presses... */ + if (event.type == evt->prevtype && evt->prevval == KM_RELEASE && event.val == KM_PRESS) { if ((ABS(event.x - evt->prevclickx)) <= 2 && (ABS(event.y - evt->prevclicky)) <= 2 && ((PIL_check_seconds_timer() - evt->prevclicktime) * 1000 < U.dbl_click_time)) { - // printf("double click\n"); + if (G.debug & (G_DEBUG_HANDLERS | G_DEBUG_EVENTS) ) + printf("%s Send double click\n", __func__); evt->val = event.val = KM_DBL_CLICK; } } - /* this case happens on some systems that on holding a key pressed, - * generate press events without release, we still want to keep the - * modifier in win->eventstate, but for the press event of the same - * key we don't want the key modifier */ + /* this case happens on holding a key pressed, it should not generate + * press events events with the same key as modifier */ if (event.keymodifier == event.type) event.keymodifier = 0; - + /* this case happened with an external numpad, it's not really clear * why, but it's also impossible to map a key modifier to an unknwon * key, so it shouldn't harm */ @@ -2972,7 +2984,8 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U if (event.type == ESCKEY && event.val == KM_PRESS) G.is_break = TRUE; - if (event.val == KM_RELEASE) { + /* double click test - only for press */ + if (event.val == KM_PRESS) { evt->prevclicktime = PIL_check_seconds_timer(); evt->prevclickx = event.x; evt->prevclicky = event.y; @@ -3002,6 +3015,8 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U event.type = TIMER; event.custom = EVT_DATA_TIMER; event.customdata = customdata; + event.val = 0; + event.keymodifier = 0; wm_event_add(win, &event); break; @@ -3010,10 +3025,12 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U case GHOST_kEventNDOFMotion: { event.type = NDOF_MOTION; + event.val = 0; attach_ndof_data(&event, customdata); wm_event_add(win, &event); - //printf("sending NDOF_MOTION, prev = %d %d\n", event.x, event.y); + if (G.debug & (G_DEBUG_HANDLERS | G_DEBUG_EVENTS) ) + printf("%s sending NDOF_MOTION, prev = %d %d\n", __func__, event.x, event.y); break; } @@ -3055,7 +3072,4 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U } - /* Handy when debugging checking events */ - /* WM_event_print(&event); */ - } diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index 5baf223dc3e..780117c73aa 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -146,7 +146,7 @@ static void wm_window_match_init(bContext *C, ListBase *wmlist) /* code copied from wm_init_exit.c */ for (wm = wmlist->first; wm; wm = wm->id.next) { - WM_jobs_stop_all(wm); + WM_jobs_kill_all(wm); for (win = wm->windows.first; win; win = win->next) { diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index 89fa92b7373..c9f0bbffc63 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -47,6 +47,10 @@ #include "DNA_userdef_types.h" #include "DNA_windowmanager_types.h" +#include "BLI_listbase.h" +#include "BLI_string.h" +#include "BLI_utildefines.h" + #include "BKE_blender.h" #include "BKE_context.h" #include "BKE_screen.h" @@ -66,10 +70,6 @@ #include "BKE_material.h" /* clear_matcopybuf */ #include "BKE_tracking.h" /* free tracking clipboard */ -#include "BLI_listbase.h" -#include "BLI_string.h" -#include "BLI_utildefines.h" - #include "RE_engine.h" #include "RE_pipeline.h" /* RE_ free stuff */ @@ -372,7 +372,7 @@ void WM_exit_ext(bContext *C, const short do_python) if (C && wm) { wmWindow *win; - WM_jobs_stop_all(wm); + WM_jobs_kill_all(wm); for (win = wm->windows.first; win; win = win->next) { diff --git a/source/blender/windowmanager/intern/wm_jobs.c b/source/blender/windowmanager/intern/wm_jobs.c index 0917d766051..42d721327b6 100644 --- a/source/blender/windowmanager/intern/wm_jobs.c +++ b/source/blender/windowmanager/intern/wm_jobs.c @@ -360,7 +360,7 @@ void WM_jobs_start(wmWindowManager *wm, wmJob *wm_job) } } -/* stop job, free data completely */ +/* stop job, end thread, free data completely */ static void wm_jobs_kill_job(wmWindowManager *wm, wmJob *wm_job) { if (wm_job->running) { @@ -385,7 +385,8 @@ static void wm_jobs_kill_job(wmWindowManager *wm, wmJob *wm_job) } -void WM_jobs_stop_all(wmWindowManager *wm) +/* wait until every job ended */ +void WM_jobs_kill_all(wmWindowManager *wm) { wmJob *wm_job; @@ -394,6 +395,18 @@ void WM_jobs_stop_all(wmWindowManager *wm) } +/* wait until every job ended, except for one owner (used in undo to keep screen job alive) */ +void WM_jobs_kill_all_except(wmWindowManager *wm, void *owner) +{ + wmJob *wm_job; + + for (wm_job = wm->jobs.first; wm_job; wm_job = wm_job->next) { + if (wm_job->owner != owner) + wm_jobs_kill_job(wm, wm_job); + } +} + + /* signal job(s) from this owner or callback to stop, timer is required to get handled */ void WM_jobs_stop(wmWindowManager *wm, void *owner, void *startjob) { diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c index bcddc984ed3..7aa2b403897 100644 --- a/source/blender/windowmanager/intern/wm_keymap.c +++ b/source/blender/windowmanager/intern/wm_keymap.c @@ -190,9 +190,9 @@ wmKeyConfig *WM_keyconfig_new_user(wmWindowManager *wm, const char *idname) return keyconf; } -void WM_keyconfig_remove(wmWindowManager *wm, wmKeyConfig *keyconf) +int WM_keyconfig_remove(wmWindowManager *wm, wmKeyConfig *keyconf) { - if (keyconf) { + if (BLI_findindex(&wm->keyconfigs, keyconf) != -1) { if (strncmp(U.keyconfigstr, keyconf->idname, sizeof(U.keyconfigstr)) == 0) { BLI_strncpy(U.keyconfigstr, wm->defaultconf->idname, sizeof(U.keyconfigstr)); WM_keyconfig_update_tag(NULL, NULL); @@ -200,6 +200,11 @@ void WM_keyconfig_remove(wmWindowManager *wm, wmKeyConfig *keyconf) BLI_remlink(&wm->keyconfigs, keyconf); WM_keyconfig_free(keyconf); + + return TRUE; + } + else { + return FALSE; } } @@ -381,7 +386,7 @@ wmKeyMapItem *WM_keymap_add_menu(wmKeyMap *keymap, const char *idname, int type, return kmi; } -void WM_keymap_remove_item(wmKeyMap *keymap, wmKeyMapItem *kmi) +int WM_keymap_remove_item(wmKeyMap *keymap, wmKeyMapItem *kmi) { if (BLI_findindex(&keymap->items, kmi) != -1) { if (kmi->ptr) { @@ -391,6 +396,10 @@ void WM_keymap_remove_item(wmKeyMap *keymap, wmKeyMapItem *kmi) BLI_freelinkN(&keymap->items, kmi); WM_keyconfig_update_tag(keymap, kmi); + return TRUE; + } + else { + return FALSE; } } @@ -816,7 +825,7 @@ char *WM_keymap_item_to_string(wmKeyMapItem *kmi, char *str, int len) static wmKeyMapItem *wm_keymap_item_find_handlers( const bContext *C, ListBase *handlers, const char *opname, int UNUSED(opcontext), - IDProperty *properties, int compare_props, int hotkey, wmKeyMap **keymap_r) + IDProperty *properties, int is_strict, int hotkey, wmKeyMap **keymap_r) { wmWindowManager *wm = CTX_wm_manager(C); wmEventHandler *handler; @@ -834,9 +843,22 @@ static wmKeyMapItem *wm_keymap_item_find_handlers( if (hotkey) if (!ISHOTKEY(kmi->type)) continue; - - if (compare_props) { - if (kmi->ptr && IDP_EqualsProperties(properties, kmi->ptr->data)) { + + if (properties) { + + /* example of debugging keymaps */ +#if 0 + if (kmi->ptr) { + if (strcmp("MESH_OT_rip_move", opname) == 0) { + printf("OPERATOR\n"); + IDP_spit(properties); + printf("KEYMAP\n"); + IDP_spit(kmi->ptr->data); + } + } +#endif + + if (kmi->ptr && IDP_EqualsProperties_ex(properties, kmi->ptr->data, is_strict)) { if (keymap_r) *keymap_r = keymap; return kmi; } @@ -857,7 +879,7 @@ static wmKeyMapItem *wm_keymap_item_find_handlers( static wmKeyMapItem *wm_keymap_item_find_props( const bContext *C, const char *opname, int opcontext, - IDProperty *properties, int compare_props, int hotkey, wmKeyMap **keymap_r) + IDProperty *properties, int is_strict, int hotkey, wmKeyMap **keymap_r) { wmWindow *win = CTX_wm_window(C); ScrArea *sa = CTX_wm_area(C); @@ -866,10 +888,10 @@ static wmKeyMapItem *wm_keymap_item_find_props( /* look into multiple handler lists to find the item */ if (win) - found = wm_keymap_item_find_handlers(C, &win->handlers, opname, opcontext, properties, compare_props, hotkey, keymap_r); + found = wm_keymap_item_find_handlers(C, &win->handlers, opname, opcontext, properties, is_strict, hotkey, keymap_r); if (sa && found == NULL) - found = wm_keymap_item_find_handlers(C, &sa->handlers, opname, opcontext, properties, compare_props, hotkey, keymap_r); + found = wm_keymap_item_find_handlers(C, &sa->handlers, opname, opcontext, properties, is_strict, hotkey, keymap_r); if (found == NULL) { if (ELEM(opcontext, WM_OP_EXEC_REGION_WIN, WM_OP_INVOKE_REGION_WIN)) { @@ -878,7 +900,7 @@ static wmKeyMapItem *wm_keymap_item_find_props( ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW); if (ar) - found = wm_keymap_item_find_handlers(C, &ar->handlers, opname, opcontext, properties, compare_props, hotkey, keymap_r); + found = wm_keymap_item_find_handlers(C, &ar->handlers, opname, opcontext, properties, is_strict, hotkey, keymap_r); } } else if (ELEM(opcontext, WM_OP_EXEC_REGION_CHANNELS, WM_OP_INVOKE_REGION_CHANNELS)) { @@ -886,18 +908,18 @@ static wmKeyMapItem *wm_keymap_item_find_props( ar = BKE_area_find_region_type(sa, RGN_TYPE_CHANNELS); if (ar) - found = wm_keymap_item_find_handlers(C, &ar->handlers, opname, opcontext, properties, compare_props, hotkey, keymap_r); + found = wm_keymap_item_find_handlers(C, &ar->handlers, opname, opcontext, properties, is_strict, hotkey, keymap_r); } else if (ELEM(opcontext, WM_OP_EXEC_REGION_PREVIEW, WM_OP_INVOKE_REGION_PREVIEW)) { if (!(ar && ar->regiontype == RGN_TYPE_PREVIEW)) ar = BKE_area_find_region_type(sa, RGN_TYPE_PREVIEW); if (ar) - found = wm_keymap_item_find_handlers(C, &ar->handlers, opname, opcontext, properties, compare_props, hotkey, keymap_r); + found = wm_keymap_item_find_handlers(C, &ar->handlers, opname, opcontext, properties, is_strict, hotkey, keymap_r); } else { if (ar) - found = wm_keymap_item_find_handlers(C, &ar->handlers, opname, opcontext, properties, compare_props, hotkey, keymap_r); + found = wm_keymap_item_find_handlers(C, &ar->handlers, opname, opcontext, properties, is_strict, hotkey, keymap_r); } } @@ -906,12 +928,28 @@ static wmKeyMapItem *wm_keymap_item_find_props( static wmKeyMapItem *wm_keymap_item_find( const bContext *C, const char *opname, int opcontext, - IDProperty *properties, const short hotkey, const short sloppy, wmKeyMap **keymap_r) + IDProperty *properties, const short hotkey, const short UNUSED(sloppy), wmKeyMap **keymap_r) { wmKeyMapItem *found = wm_keymap_item_find_props(C, opname, opcontext, properties, 1, hotkey, keymap_r); - if (!found && sloppy) - found = wm_keymap_item_find_props(C, opname, opcontext, NULL, 0, hotkey, keymap_r); + if (!found && properties) { + wmOperatorType *ot = WM_operatortype_find(opname, TRUE); + if (ot) { + /* make a copy of the properties and set any unset props + * to their default values, so the ID property compare function succeeds */ + PointerRNA opptr; + IDProperty *properties_default = IDP_CopyProperty(properties); + + RNA_pointer_create(NULL, ot->srna, properties_default, &opptr); + + if (WM_operator_properties_default(&opptr, TRUE)) { + found = wm_keymap_item_find_props(C, opname, opcontext, properties_default, 0, hotkey, keymap_r); + } + + IDP_FreeProperty(properties_default); + MEM_freeN(properties_default); + } + } return found; } diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index af6ec370fea..2ef33aa5964 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -619,6 +619,42 @@ void WM_operator_properties_sanitize(PointerRNA *ptr, const short no_context) RNA_STRUCT_END; } + +/** set all props to their default, + * \param do_update Only update un-initialized props. + * + * \note, theres nothing spesific to operators here. + * this could be made a general function. + */ +int WM_operator_properties_default(PointerRNA *ptr, const int do_update) +{ + int is_change = FALSE; + RNA_STRUCT_BEGIN(ptr, prop) + { + switch (RNA_property_type(prop)) { + case PROP_POINTER: + { + StructRNA *ptype = RNA_property_pointer_type(ptr, prop); + if (ptype != &RNA_Struct) { + PointerRNA opptr = RNA_property_pointer_get(ptr, prop); + is_change |= WM_operator_properties_default(&opptr, do_update); + } + break; + } + default: + if ((do_update == FALSE) || (RNA_property_is_set(ptr, prop) == FALSE)) { + if (RNA_property_reset(ptr, prop, -1)) { + is_change = 1; + } + } + break; + } + } + RNA_STRUCT_END; + + return is_change; +} + /* remove all props without PROP_SKIP_SAVE */ void WM_operator_properties_reset(wmOperator *op) { @@ -859,6 +895,8 @@ void WM_operator_properties_filesel(wmOperatorType *ot, int filter, short type, RNA_def_collection_runtime(ot->srna, "files", &RNA_OperatorFileListElement, "Files", ""); if (action == FILE_SAVE) { + /* note, this is only used to check if we should highlight the filename area red when the + * filepath is an existing file. */ prop = RNA_def_boolean(ot->srna, "check_existing", 1, "Check Existing", "Check and warn on overwriting existing files"); RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); } @@ -2117,7 +2155,6 @@ static void WM_OT_save_as_mainfile(wmOperatorType *ot) static int wm_save_mainfile_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) { char name[FILE_MAX]; - int check_existing = 1; int ret; /* cancel if no active window */ @@ -2137,13 +2174,9 @@ static int wm_save_mainfile_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED( untitled(name); RNA_string_set(op->ptr, "filepath", name); - - if (RNA_struct_find_property(op->ptr, "check_existing")) - if (RNA_boolean_get(op->ptr, "check_existing") == 0) - check_existing = 0; - + if (G.save_over) { - if (check_existing && BLI_exists(name)) { + if (BLI_exists(name)) { uiPupMenuSaveOver(C, op, name); ret = OPERATOR_RUNNING_MODAL; } diff --git a/source/blender/windowmanager/intern/wm_playanim.c b/source/blender/windowmanager/intern/wm_playanim.c index cf5bce568d5..96bbedfee1b 100644 --- a/source/blender/windowmanager/intern/wm_playanim.c +++ b/source/blender/windowmanager/intern/wm_playanim.c @@ -590,8 +590,8 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void) break; case GHOST_kKeyNumpadPlus: if (val == 0) break; - zoomx += 2.0; - zoomy += 2.0; + zoomx += 2.0f; + zoomy += 2.0f; /* no break??? - is this intentional? - campbell XXX25 */ case GHOST_kKeyNumpadMinus: { @@ -599,8 +599,8 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void) /* int ofsx, ofsy; */ /* UNUSED */ if (val == 0) break; - if (zoomx > 1.0) zoomx -= 1.0; - if (zoomy > 1.0) zoomy -= 1.0; + if (zoomx > 1.0f) zoomx -= 1.0f; + if (zoomy > 1.0f) zoomy -= 1.0f; // playanim_window_get_position(&ofsx, &ofsy); playanim_window_get_size(&sizex, &sizey); /* ofsx += sizex / 2; */ /* UNUSED */ @@ -665,10 +665,10 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void) zoomx = (float) sizex / ps->ibufx; zoomy = (float) sizey / ps->ibufy; - zoomx = floor(zoomx + 0.5); - zoomy = floor(zoomy + 0.5); - if (zoomx < 1.0) zoomx = 1.0; - if (zoomy < 1.0) zoomy = 1.0; + zoomx = floor(zoomx + 0.5f); + zoomy = floor(zoomy + 0.5f); + if (zoomx < 1.0f) zoomx = 1.0f; + if (zoomy < 1.0f) zoomy = 1.0f; sizex = zoomx * ps->ibufx; sizey = zoomy * ps->ibufy; diff --git a/source/blender/windowmanager/intern/wm_subwindow.c b/source/blender/windowmanager/intern/wm_subwindow.c index e33f936b4da..8533494ae96 100644 --- a/source/blender/windowmanager/intern/wm_subwindow.c +++ b/source/blender/windowmanager/intern/wm_subwindow.c @@ -163,10 +163,6 @@ int wm_subwindow_open(wmWindow *win, rcti *winrct) win->curswin = swin = MEM_callocN(sizeof(wmSubWindow), "swinopen"); BLI_addtail(&win->subwindows, swin); - if (G.debug & G_DEBUG_EVENTS) { - printf("%s: swin %d added\n", __func__, freewinid); - } - swin->swinid = freewinid; swin->winrct = *winrct; diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index 7d5dc858b00..616567e8184 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -945,6 +945,8 @@ static int wm_window_timer(const bContext *C) wmEvent event = *(win->eventstate); event.type = wt->event_type; + event.val = 0; + event.keymodifier = 0; event.custom = EVT_DATA_TIMER; event.customdata = wt; wm_event_add(win, &event); diff --git a/source/blender/windowmanager/wm_event_types.h b/source/blender/windowmanager/wm_event_types.h index 95a8a7db635..ca0e9659a22 100644 --- a/source/blender/windowmanager/wm_event_types.h +++ b/source/blender/windowmanager/wm_event_types.h @@ -285,8 +285,9 @@ enum { /* for event checks */ /* only used for KM_TEXTINPUT, so assume that we want all user-inputtable ascii codes included */ + /* UNUSED - see wm_eventmatch - BUG [#30479] #define ISTEXTINPUT(event) (event >= ' ' && event <= 255) - + */ /* test whether the event is a key on the keyboard */ #define ISKEYBOARD(event) (event >= ' ' && event <= 320) diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c index f33fe8c6538..41741dd9a5b 100644 --- a/source/blenderplayer/bad_level_call_stubs/stubs.c +++ b/source/blenderplayer/bad_level_call_stubs/stubs.c @@ -201,7 +201,7 @@ struct MenuType *WM_menutype_find(const char *idname, int quiet) {return (struct void WM_operator_stack_clear(struct bContext *C) {} void WM_autosave_init(struct bContext *C) {} -void WM_jobs_stop_all(struct wmWindowManager *wm) {} +void WM_jobs_kill_all_except(struct wmWindowManager *wm) {} char *WM_clipboard_text_get(int selection) {return (char*)0;} void WM_clipboard_text_set(char *buf, int selection) {} diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt index 682ab5013d6..f986e30b10c 100644 --- a/source/creator/CMakeLists.txt +++ b/source/creator/CMakeLists.txt @@ -738,14 +738,6 @@ elseif(APPLE) endif() - #OSL shader_headers needed - if(WITH_CYCLES_OSL) - install( - FILES ${LIBDIR}/osl/shaders/oslutil.h ${LIBDIR}/osl/shaders/stdosl.h - DESTINATION ${TARGETDIR}/blender.app/Contents/shaders/ - ) - endif() - # install blenderplayer bundle - copy of blender.app above. re-using macros et al # note we are using OSX Bundle as base and copying Blender dummy bundle on top of it if(WITH_GAMEENGINE AND WITH_PLAYER) diff --git a/source/gameengine/BlenderRoutines/KX_BlenderInputDevice.h b/source/gameengine/BlenderRoutines/KX_BlenderInputDevice.h index a183d4059f8..2a96d4c5216 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderInputDevice.h +++ b/source/gameengine/BlenderRoutines/KX_BlenderInputDevice.h @@ -48,8 +48,9 @@ #endif /** - Base Class for Blender specific inputdevices. Blender specific inputdevices are used when the gameengine is running in embedded mode instead of standalone mode. -*/ + * Base Class for Blender specific inputdevices. + * Blender specific inputdevices are used when the gameengine is running in embedded mode instead of standalone mode. + */ class BL_BlenderInputDevice : public SCA_IInputDevice { public: diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index 982988cc088..58ae415e9d3 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -1587,8 +1587,16 @@ static void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj, //bool bRigidBody = (userigidbody == 0); // object has physics representation? - if (!(blenderobject->gameflag & OB_COLLISION)) + if (!(blenderobject->gameflag & OB_COLLISION)) { + // Respond to all collisions so that Near sensors work on No Collision + // objects. + gameobj->SetUserCollisionGroup(0xff); + gameobj->SetUserCollisionMask(0xff); return; + } + + gameobj->SetUserCollisionGroup(blenderobject->col_group); + gameobj->SetUserCollisionMask(blenderobject->col_mask); // get Root Parent of blenderobject struct Object* parent= blenderobject->parent; diff --git a/source/gameengine/Converter/KX_ConvertSensors.cpp b/source/gameengine/Converter/KX_ConvertSensors.cpp index d3d3256312e..538f9e2c833 100644 --- a/source/gameengine/Converter/KX_ConvertSensors.cpp +++ b/source/gameengine/Converter/KX_ConvertSensors.cpp @@ -632,9 +632,9 @@ void BL_ConvertSensors(struct Object* blenderobject, uniqueval->Release(); /* Conversion succeeded, so we can set the generic props here. */ - gamesensor->SetPulseMode(pos_pulsemode, - neg_pulsemode, - frequency); + gamesensor->SetPulseMode(pos_pulsemode, + neg_pulsemode, + frequency); gamesensor->SetInvert(invert); gamesensor->SetLevel(level); gamesensor->SetTap(tap); diff --git a/source/gameengine/GameLogic/SCA_RandomActuator.cpp b/source/gameengine/GameLogic/SCA_RandomActuator.cpp index 9a54c76ed4e..2d51a45fe55 100644 --- a/source/gameengine/GameLogic/SCA_RandomActuator.cpp +++ b/source/gameengine/GameLogic/SCA_RandomActuator.cpp @@ -48,13 +48,13 @@ /* ------------------------------------------------------------------------- */ SCA_RandomActuator::SCA_RandomActuator(SCA_IObject *gameobj, - long seed, - SCA_RandomActuator::KX_RANDOMACT_MODE mode, - float para1, - float para2, - const STR_String &propName) - : SCA_IActuator(gameobj, KX_ACT_RANDOM), - m_propname(propName), + long seed, + SCA_RandomActuator::KX_RANDOMACT_MODE mode, + float para1, + float para2, + const STR_String &propName) + : SCA_IActuator(gameobj, KX_ACT_RANDOM), + m_propname(propName), m_parameter1(para1), m_parameter2(para2), m_distribution(mode) @@ -196,33 +196,30 @@ bool SCA_RandomActuator::Update() */ tmpval = new CFloatValue(m_parameter1); - } else { - /* - - 070301 - nzc - Now, with seed != 0, we will most assuredly get some - sensible values. The termination condition states two - things: - 1. s >= 0 is not allowed: to prevent the distro from - getting a bias towards high values. This is a small - correction, really, and might also be left out. - 2. s == 0 is not allowed: to prevent a division by zero - when renormalising the drawn value to the desired - distribution shape. As a side effect, the distro will - never yield the exact mean. - I am not sure whether this is consistent, since the error - cause by #2 is of the same magnitude as the one - prevented by #1. The error introduced into the SD will be - improved, though. By how much? Hard to say... If you like - the maths, feel free to analyse. Be aware that this is - one of the really old standard algorithms. I think the - original came in Fortran, was translated to Pascal, and - then someone came up with the C code. My guess it that - this will be quite sufficient here. - + } + else { + /* 070301 - nzc + * Now, with seed != 0, we will most assuredly get some + * sensible values. The termination condition states two + * things: + * 1. s >= 0 is not allowed: to prevent the distro from + * getting a bias towards high values. This is a small + * correction, really, and might also be left out. + * 2. s == 0 is not allowed: to prevent a division by zero + * when renormalising the drawn value to the desired + * distribution shape. As a side effect, the distro will + * never yield the exact mean. + * I am not sure whether this is consistent, since the error + * cause by #2 is of the same magnitude as the one + * prevented by #1. The error introduced into the SD will be + * improved, though. By how much? Hard to say... If you like + * the maths, feel free to analyse. Be aware that this is + * one of the really old standard algorithms. I think the + * original came in Fortran, was translated to Pascal, and + * then someone came up with the C code. My guess it that + * this will be quite sufficient here. */ - do - { + do { x = 2.0 * m_base->DrawFloat() - 1.0; y = 2.0 * m_base->DrawFloat() - 1.0; s = x*x + y*y; diff --git a/source/gameengine/GamePlayer/CMakeLists.txt b/source/gameengine/GamePlayer/CMakeLists.txt index cdf3f826ea9..e1a26668d11 100644 --- a/source/gameengine/GamePlayer/CMakeLists.txt +++ b/source/gameengine/GamePlayer/CMakeLists.txt @@ -26,6 +26,6 @@ add_subdirectory(common) add_subdirectory(ghost) -if(WITH_WEBPLUGIN) +if(WITH_WEBPLUGIN) add_subdirectory(xembed) endif() diff --git a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp index 9006a629791..725c23c60e3 100644 --- a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp +++ b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp @@ -119,11 +119,11 @@ static void mem_error_cb(const char *errorStr) #ifdef WIN32 typedef enum { - SCREEN_SAVER_MODE_NONE = 0, - SCREEN_SAVER_MODE_PREVIEW, - SCREEN_SAVER_MODE_SAVER, - SCREEN_SAVER_MODE_CONFIGURATION, - SCREEN_SAVER_MODE_PASSWORD, + SCREEN_SAVER_MODE_NONE = 0, + SCREEN_SAVER_MODE_PREVIEW, + SCREEN_SAVER_MODE_SAVER, + SCREEN_SAVER_MODE_CONFIGURATION, + SCREEN_SAVER_MODE_PASSWORD, } ScreenSaverMode; static ScreenSaverMode scr_saver_mode = SCREEN_SAVER_MODE_NONE; diff --git a/source/gameengine/Ketsji/BL_BlenderShader.cpp b/source/gameengine/Ketsji/BL_BlenderShader.cpp index b2dfefd9e0b..23bfd7a111b 100644 --- a/source/gameengine/Ketsji/BL_BlenderShader.cpp +++ b/source/gameengine/Ketsji/BL_BlenderShader.cpp @@ -6,6 +6,8 @@ #include "DNA_material_types.h" #include "DNA_scene_types.h" +#include "BLI_utildefines.h" + #include "BKE_global.h" #include "BKE_main.h" #include "BKE_DerivedMesh.h" diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp index da6fd822a6b..2154beeb205 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp @@ -165,11 +165,11 @@ void KX_BlenderMaterial::InitTextures() continue; } if (!mTextures[i].InitCubeMap(i, mMaterial->cubemap[i] ) ) - spit("unable to initialize image("<<i<<") in "<< - mMaterial->matname<< ", image will not be available"); - } - // If we're using glsl materials, the textures are handled by bf_gpu, so don't load them twice! - // However, if we're using a custom shader, then we still need to load the textures ourselves. + spit("unable to initialize image("<<i<<") in "<< + mMaterial->matname<< ", image will not be available"); + } + /* If we're using glsl materials, the textures are handled by bf_gpu, so don't load them twice! + * However, if we're using a custom shader, then we still need to load the textures ourselves. */ else if (!mMaterial->glslmat || mShader) { if ( mMaterial->img[i] ) { if ( ! mTextures[i].InitFromImage(i, mMaterial->img[i], (mMaterial->flag[i] &MIPMAP)!=0 )) diff --git a/source/gameengine/Ketsji/KX_Camera.cpp b/source/gameengine/Ketsji/KX_Camera.cpp index 3cc51361788..39b0a24865e 100644 --- a/source/gameengine/Ketsji/KX_Camera.cpp +++ b/source/gameengine/Ketsji/KX_Camera.cpp @@ -38,19 +38,19 @@ #include "KX_Python.h" #include "KX_PyMath.h" KX_Camera::KX_Camera(void* sgReplicationInfo, - SG_Callbacks callbacks, - const RAS_CameraData& camdata, - bool frustum_culling, - bool delete_node) - : - KX_GameObject(sgReplicationInfo,callbacks), - m_camdata(camdata), - m_dirty(true), - m_normalized(false), - m_frustum_culling(frustum_culling), - m_set_projection_matrix(false), - m_set_frustum_center(false), - m_delete_node(delete_node) + SG_Callbacks callbacks, + const RAS_CameraData& camdata, + bool frustum_culling, + bool delete_node) + : + KX_GameObject(sgReplicationInfo,callbacks), + m_camdata(camdata), + m_dirty(true), + m_normalized(false), + m_frustum_culling(frustum_culling), + m_set_projection_matrix(false), + m_set_frustum_center(false), + m_delete_node(delete_node) { // setting a name would be nice... m_name = "cam"; diff --git a/source/gameengine/Ketsji/KX_Camera.h b/source/gameengine/Ketsji/KX_Camera.h index 6c1dc1edb51..f615fefc223 100644 --- a/source/gameengine/Ketsji/KX_Camera.h +++ b/source/gameengine/Ketsji/KX_Camera.h @@ -120,7 +120,7 @@ protected: /** * whether the camera should delete the node itself (only for shadow camera) */ - bool m_delete_node; + bool m_delete_node; /** * Extracts the camera clip frames from the projection and world-to-camera matrices. diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp index daa74ca14c0..ff3c46cb8ab 100644 --- a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp +++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp @@ -54,6 +54,7 @@ #include "KX_MotionState.h" // bridge between motionstate and scenegraph node extern "C"{ + #include "BLI_utildefines.h" #include "BKE_DerivedMesh.h" } diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index 48a45c2d1c2..a669f4346ea 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -531,6 +531,19 @@ void KX_GameObject::ActivateGraphicController(bool recurse) } } +void KX_GameObject::SetUserCollisionGroup(short group) +{ + m_userCollisionGroup = group; +} +void KX_GameObject::SetUserCollisionMask(short mask) +{ + m_userCollisionMask = mask; +} + +bool KX_GameObject::CheckCollision(KX_GameObject* other) +{ + return this->m_userCollisionGroup & other->m_userCollisionMask; +} CValue* KX_GameObject::GetReplica() { diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h index 5ceef2c60c9..d5ae13eb702 100644 --- a/source/gameengine/Ketsji/KX_GameObject.h +++ b/source/gameengine/Ketsji/KX_GameObject.h @@ -98,6 +98,10 @@ protected: bool m_bIsNegativeScaling; MT_Vector4 m_objectColor; + // Bit fields for user control over physics collisions + short m_userCollisionGroup; + short m_userCollisionMask; + // visible = user setting // culled = while rendering, depending on camera bool m_bVisible; @@ -494,6 +498,13 @@ public: */ void ActivateGraphicController(bool recurse); + void SetUserCollisionGroup(short filter); + void SetUserCollisionMask(short mask); + /** + * Extra broadphase check for user controllable collisions + */ + bool CheckCollision(KX_GameObject *other); + /** * \section Coordinate system manipulation functions */ diff --git a/source/gameengine/Ketsji/KX_IPOTransform.h b/source/gameengine/Ketsji/KX_IPOTransform.h index 43019f3e54a..a68292bf9df 100644 --- a/source/gameengine/Ketsji/KX_IPOTransform.h +++ b/source/gameengine/Ketsji/KX_IPOTransform.h @@ -48,8 +48,8 @@ public: MT_Transform GetTransform() const { return MT_Transform(m_position + m_deltaPosition, - MT_Matrix3x3(m_eulerAngles + m_deltaEulerAngles, - m_scaling + m_deltaScaling)); + MT_Matrix3x3(m_eulerAngles + m_deltaEulerAngles, + m_scaling + m_deltaScaling)); } MT_Point3& GetPosition() { return m_position; } diff --git a/source/gameengine/Ketsji/KX_IPO_SGController.cpp b/source/gameengine/Ketsji/KX_IPO_SGController.cpp index 60821fb5aab..c5e11195547 100644 --- a/source/gameengine/Ketsji/KX_IPO_SGController.cpp +++ b/source/gameengine/Ketsji/KX_IPO_SGController.cpp @@ -52,7 +52,7 @@ typedef unsigned long uint_ptr; // All objects should start on frame 1! Will we ever need an object to // start on another frame, the 1.0 should change. -KX_IpoSGController::KX_IpoSGController() +KX_IpoSGController::KX_IpoSGController() : m_ipo_as_force(false), m_ipo_add(false), m_ipo_local(false), diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp index a85575d4f55..0ab7b9ec9e5 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp @@ -1436,8 +1436,17 @@ void KX_KetsjiEngine::PostProcessScene(KX_Scene* scene) void KX_KetsjiEngine::RenderDebugProperties() { STR_String debugtxt; - int xcoord = 10; // mmmm, these constants were taken from blender source - int ycoord = 14; // to 'mimic' behavior + int title_xmargin = -7; + int title_y_top_margin = 4; + int title_y_bottom_margin = 2; + + int const_xindent = 4; + int const_ysize = 14; + + int xcoord = 12; // mmmm, these constants were taken from blender source + int ycoord = 17; // to 'mimic' behavior + + int profile_indent = 64; float tottime = m_logger->GetAverage(); if (tottime < 1e-6f) { @@ -1448,19 +1457,44 @@ void KX_KetsjiEngine::RenderDebugProperties() RAS_Rect viewport; m_canvas->SetViewPort(0, 0, int(m_canvas->GetWidth()), int(m_canvas->GetHeight())); + if (m_show_framerate || m_show_profile) { + /* Title for profiling("Profile") */ + debugtxt.Format("Profile"); + m_rendertools->RenderText2D(RAS_IRenderTools::RAS_TEXT_PADDED, + debugtxt.Ptr(), + xcoord + const_xindent + title_xmargin, // Adds the constant x indent (0 for now) to the title x margin + ycoord, + m_canvas->GetWidth() /* RdV, TODO ?? */, + m_canvas->GetHeight() /* RdV, TODO ?? */); + + // Increase the indent by default increase + ycoord += const_ysize; + // Add the title indent afterwards + ycoord += title_y_bottom_margin; + } + /* Framerate display */ if (m_show_framerate) { - debugtxt.Format("swap : %.3f (%.3f frames per second)", tottime, 1.0/tottime); + debugtxt.Format("Frametime :"); m_rendertools->RenderText2D(RAS_IRenderTools::RAS_TEXT_PADDED, debugtxt.Ptr(), - xcoord, + xcoord + const_xindent, ycoord, - m_canvas->GetWidth() /* RdV, TODO ?? */, + m_canvas->GetWidth() /* RdV, TODO ?? */, m_canvas->GetHeight() /* RdV, TODO ?? */); - ycoord += 14; + + debugtxt.Format("%5.1fms (%5.1f fps)", tottime * 1000.f, 1.0/tottime); + m_rendertools->RenderText2D(RAS_IRenderTools::RAS_TEXT_PADDED, + debugtxt.Ptr(), + xcoord + const_xindent + profile_indent, + ycoord, + m_canvas->GetWidth() /* RdV, TODO ?? */, + m_canvas->GetHeight() /* RdV, TODO ?? */); + // Increase the indent by default increase + ycoord += const_ysize; } - /* Profile and framerate display */ + /* Profile display */ if (m_show_profile) { for (int j = tc_first; j < tc_numCategories; j++) @@ -1468,23 +1502,43 @@ void KX_KetsjiEngine::RenderDebugProperties() debugtxt.Format(m_profileLabels[j]); m_rendertools->RenderText2D(RAS_IRenderTools::RAS_TEXT_PADDED, debugtxt.Ptr(), - xcoord,ycoord, + xcoord + const_xindent, + ycoord, m_canvas->GetWidth(), m_canvas->GetHeight()); + double time = m_logger->GetAverage((KX_TimeCategory)j); - debugtxt.Format("%.3fms (%2.2f %%)", time*1000.f, time/tottime * 100.f); + + debugtxt.Format("%5.2fms (%2d%%)", time*1000.f, (int)(time/tottime * 100.f)); m_rendertools->RenderText2D(RAS_IRenderTools::RAS_TEXT_PADDED, debugtxt.Ptr(), - xcoord + 60, ycoord, + xcoord + const_xindent + profile_indent, ycoord, m_canvas->GetWidth(), m_canvas->GetHeight()); - ycoord += 14; + ycoord += const_ysize; } } + // Add the ymargin for titles below the other section of debug info + ycoord += title_y_top_margin; /* Property display*/ if (m_show_debug_properties && m_propertiesPresent) { + + /* Title for debugging("Debug properties") */ + debugtxt.Format("Debug Properties"); + m_rendertools->RenderText2D(RAS_IRenderTools::RAS_TEXT_PADDED, + debugtxt.Ptr(), + xcoord + const_xindent + title_xmargin, // Adds the constant x indent (0 for now) to the title x margin + ycoord, + m_canvas->GetWidth() /* RdV, TODO ?? */, + m_canvas->GetHeight() /* RdV, TODO ?? */); + + // Increase the indent by default increase + ycoord += const_ysize; + // Add the title indent afterwards + ycoord += title_y_bottom_margin; + KX_SceneList::iterator sceneit; for (sceneit = m_scenes.begin();sceneit != m_scenes.end() ; sceneit++) { @@ -1519,11 +1573,11 @@ void KX_KetsjiEngine::RenderDebugProperties() } m_rendertools->RenderText2D(RAS_IRenderTools::RAS_TEXT_PADDED, debugtxt.Ptr(), - xcoord, + xcoord + const_xindent, ycoord, m_canvas->GetWidth(), m_canvas->GetHeight()); - ycoord += 14; + ycoord += const_ysize; } else { @@ -1531,14 +1585,14 @@ void KX_KetsjiEngine::RenderDebugProperties() if (propval) { STR_String text = propval->GetText(); - debugtxt = objname + "." + propname + " = " + text; + debugtxt = objname + ": '" + propname + "' = " + text; m_rendertools->RenderText2D(RAS_IRenderTools::RAS_TEXT_PADDED, debugtxt.Ptr(), - xcoord, + xcoord + const_xindent, ycoord, m_canvas->GetWidth(), m_canvas->GetHeight()); - ycoord += 14; + ycoord += const_ysize; } } } diff --git a/source/gameengine/Ketsji/KX_MouseFocusSensor.h b/source/gameengine/Ketsji/KX_MouseFocusSensor.h index a8376dcb4fb..1f7809831e7 100644 --- a/source/gameengine/Ketsji/KX_MouseFocusSensor.h +++ b/source/gameengine/Ketsji/KX_MouseFocusSensor.h @@ -151,27 +151,27 @@ class KX_MouseFocusSensor : public SCA_MouseSensor /** * (in game world coordinates) the place where the object was hit. */ - MT_Point3 m_hitPosition; + MT_Point3 m_hitPosition; /** * (in game world coordinates) the position to which to shoot the ray. */ - MT_Point3 m_prevTargetPoint; + MT_Point3 m_prevTargetPoint; /** * (in game world coordinates) the position from which to shoot the ray. */ - MT_Point3 m_prevSourcePoint; - + MT_Point3 m_prevSourcePoint; + /** * (in game world coordinates) the face normal of the vertex where * the object was hit. */ - MT_Vector3 m_hitNormal; + MT_Vector3 m_hitNormal; /** * UV texture coordinate of the hit point if any, (0,0) otherwise */ - MT_Vector2 m_hitUV; + MT_Vector2 m_hitUV; /** * The KX scene that holds the camera. The camera position diff --git a/source/gameengine/Ketsji/KX_ObjectActuator.cpp b/source/gameengine/Ketsji/KX_ObjectActuator.cpp index 9cebf9cfc82..2999550fb8f 100644 --- a/source/gameengine/Ketsji/KX_ObjectActuator.cpp +++ b/source/gameengine/Ketsji/KX_ObjectActuator.cpp @@ -114,7 +114,14 @@ bool KX_ObjectActuator::Update() (m_bitLocalFlag.AngularVelocity) != 0 ); m_active_combined_velocity = false; - } + } + + // Explicitly stop the movement if we're using a character (apply movement is a little different for characters) + if (parent->GetPhysicsController()->IsCharacter()) { + MT_Vector3 vec(0.0, 0.0, 0.0); + parent->ApplyMovement(vec, true); + } + m_linear_damping_active = false; m_angular_damping_active = false; m_error_accumulator.setValue(0.0,0.0,0.0); diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index 2c147528bcb..7f6655861f1 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -180,8 +180,8 @@ void KX_RasterizerDrawDebugLine(const MT_Vector3& from,const MT_Vector3& to,cons gp_Rasterizer->DrawDebugLine(from,to,color); } -void KX_RasterizerDrawDebugCircle(const MT_Vector3& center, const MT_Scalar radius, const MT_Vector3& color, - const MT_Vector3& normal, int nsector) +void KX_RasterizerDrawDebugCircle(const MT_Vector3& center, const MT_Scalar radius, const MT_Vector3& color, + const MT_Vector3& normal, int nsector) { if (gp_Rasterizer) gp_Rasterizer->DrawDebugCircle(center, radius, color, normal, nsector); @@ -1311,48 +1311,47 @@ static PyObject *gPySetWindowSize(PyObject *, PyObject *args) } static struct PyMethodDef rasterizer_methods[] = { - {"getWindowWidth",(PyCFunction) gPyGetWindowWidth, - METH_VARARGS, "getWindowWidth doc"}, - {"getWindowHeight",(PyCFunction) gPyGetWindowHeight, - METH_VARARGS, "getWindowHeight doc"}, - {"makeScreenshot",(PyCFunction)gPyMakeScreenshot, - METH_VARARGS, "make Screenshot doc"}, - {"enableVisibility",(PyCFunction) gPyEnableVisibility, - METH_VARARGS, "enableVisibility doc"}, + {"getWindowWidth",(PyCFunction) gPyGetWindowWidth, + METH_VARARGS, "getWindowWidth doc"}, + {"getWindowHeight",(PyCFunction) gPyGetWindowHeight, + METH_VARARGS, "getWindowHeight doc"}, + {"makeScreenshot",(PyCFunction)gPyMakeScreenshot, + METH_VARARGS, "make Screenshot doc"}, + {"enableVisibility",(PyCFunction) gPyEnableVisibility, + METH_VARARGS, "enableVisibility doc"}, {"showMouse",(PyCFunction) gPyShowMouse, - METH_VARARGS, "showMouse(bool visible)"}, - {"setMousePosition",(PyCFunction) gPySetMousePosition, - METH_VARARGS, "setMousePosition(int x,int y)"}, - {"setBackgroundColor",(PyCFunction)gPySetBackgroundColor,METH_O,"set Background Color (rgb)"}, + METH_VARARGS, "showMouse(bool visible)"}, + {"setMousePosition",(PyCFunction) gPySetMousePosition, + METH_VARARGS, "setMousePosition(int x,int y)"}, + {"setBackgroundColor",(PyCFunction)gPySetBackgroundColor,METH_O,"set Background Color (rgb)"}, {"setAmbientColor",(PyCFunction)gPySetAmbientColor,METH_O,"set Ambient Color (rgb)"}, - {"disableMist",(PyCFunction)gPyDisableMist,METH_NOARGS,"turn off mist"}, - {"setMistColor",(PyCFunction)gPySetMistColor,METH_O,"set Mist Color (rgb)"}, - {"setMistStart",(PyCFunction)gPySetMistStart,METH_VARARGS,"set Mist Start(rgb)"}, - {"setMistEnd",(PyCFunction)gPySetMistEnd,METH_VARARGS,"set Mist End(rgb)"}, - {"enableMotionBlur",(PyCFunction)gPyEnableMotionBlur,METH_VARARGS,"enable motion blur"}, - {"disableMotionBlur",(PyCFunction)gPyDisableMotionBlur,METH_NOARGS,"disable motion blur"}, - - - {"setEyeSeparation", (PyCFunction) gPySetEyeSeparation, METH_VARARGS, "set the eye separation for stereo mode"}, - {"getEyeSeparation", (PyCFunction) gPyGetEyeSeparation, METH_NOARGS, "get the eye separation for stereo mode"}, - {"setFocalLength", (PyCFunction) gPySetFocalLength, METH_VARARGS, "set the focal length for stereo mode"}, - {"getFocalLength", (PyCFunction) gPyGetFocalLength, METH_VARARGS, "get the focal length for stereo mode"}, - {"setMaterialMode",(PyCFunction) gPySetMaterialType, - METH_VARARGS, "set the material mode to use for OpenGL rendering"}, - {"getMaterialMode",(PyCFunction) gPyGetMaterialType, - METH_NOARGS, "get the material mode being used for OpenGL rendering"}, - {"setGLSLMaterialSetting",(PyCFunction) gPySetGLSLMaterialSetting, - METH_VARARGS, "set the state of a GLSL material setting"}, - {"getGLSLMaterialSetting",(PyCFunction) gPyGetGLSLMaterialSetting, - METH_VARARGS, "get the state of a GLSL material setting"}, - {"setAnisotropicFiltering", (PyCFunction) gPySetAnisotropicFiltering, - METH_VARARGS, "set the anisotropic filtering level (must be one of 1, 2, 4, 8, 16)"}, - {"getAnisotropicFiltering", (PyCFunction) gPyGetAnisotropicFiltering, - METH_VARARGS, "get the anisotropic filtering level"}, - {"drawLine", (PyCFunction) gPyDrawLine, - METH_VARARGS, "draw a line on the screen"}, - {"setWindowSize", (PyCFunction) gPySetWindowSize, METH_VARARGS, ""}, - { NULL, (PyCFunction) NULL, 0, NULL } + {"disableMist",(PyCFunction)gPyDisableMist,METH_NOARGS,"turn off mist"}, + {"setMistColor",(PyCFunction)gPySetMistColor,METH_O,"set Mist Color (rgb)"}, + {"setMistStart",(PyCFunction)gPySetMistStart,METH_VARARGS,"set Mist Start(rgb)"}, + {"setMistEnd",(PyCFunction)gPySetMistEnd,METH_VARARGS,"set Mist End(rgb)"}, + {"enableMotionBlur",(PyCFunction)gPyEnableMotionBlur,METH_VARARGS,"enable motion blur"}, + {"disableMotionBlur",(PyCFunction)gPyDisableMotionBlur,METH_NOARGS,"disable motion blur"}, + + {"setEyeSeparation", (PyCFunction) gPySetEyeSeparation, METH_VARARGS, "set the eye separation for stereo mode"}, + {"getEyeSeparation", (PyCFunction) gPyGetEyeSeparation, METH_NOARGS, "get the eye separation for stereo mode"}, + {"setFocalLength", (PyCFunction) gPySetFocalLength, METH_VARARGS, "set the focal length for stereo mode"}, + {"getFocalLength", (PyCFunction) gPyGetFocalLength, METH_VARARGS, "get the focal length for stereo mode"}, + {"setMaterialMode",(PyCFunction) gPySetMaterialType, + METH_VARARGS, "set the material mode to use for OpenGL rendering"}, + {"getMaterialMode",(PyCFunction) gPyGetMaterialType, + METH_NOARGS, "get the material mode being used for OpenGL rendering"}, + {"setGLSLMaterialSetting",(PyCFunction) gPySetGLSLMaterialSetting, + METH_VARARGS, "set the state of a GLSL material setting"}, + {"getGLSLMaterialSetting",(PyCFunction) gPyGetGLSLMaterialSetting, + METH_VARARGS, "get the state of a GLSL material setting"}, + {"setAnisotropicFiltering", (PyCFunction) gPySetAnisotropicFiltering, + METH_VARARGS, "set the anisotropic filtering level (must be one of 1, 2, 4, 8, 16)"}, + {"getAnisotropicFiltering", (PyCFunction) gPyGetAnisotropicFiltering, + METH_VARARGS, "get the anisotropic filtering level"}, + {"drawLine", (PyCFunction) gPyDrawLine, + METH_VARARGS, "draw a line on the screen"}, + {"setWindowSize", (PyCFunction) gPySetWindowSize, METH_VARARGS, ""}, + { NULL, (PyCFunction) NULL, 0, NULL } }; // Initialization function for the module (*must* be called initGameLogic) diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp index 568c11a0be4..8d587cf39f6 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.cpp @@ -46,9 +46,11 @@ subject to the following restrictions: #include "DNA_meshdata_types.h" extern "C"{ -#include "BKE_cdderivedmesh.h" + #include "BLI_utildefines.h" + #include "BKE_cdderivedmesh.h" } + class BP_Proxy; ///todo: fill all the empty CcdPhysicsController methods, hook them up to the btRigidBody class @@ -230,9 +232,9 @@ bool CcdPhysicsController::CreateSoftbody() psb = new btSoftBody(&worldInfo, (int)hres.mNumOutputVertices, &hres.m_OutputVertices[0], 0); for (int i = 0; i < (int)hres.mNumFaces; ++i) { - const int idx[3] = {hres.m_Indices[i * 3 + 0], - hres.m_Indices[i * 3 + 1], - hres.m_Indices[i * 3 + 2]}; + const unsigned int idx[3] = {hres.m_Indices[i * 3 + 0], + hres.m_Indices[i * 3 + 1], + hres.m_Indices[i * 3 + 2]}; if (idx[0] < idx[1]) psb->appendLink(idx[0], idx[1]); if (idx[1] < idx[2]) psb->appendLink(idx[1], idx[2]); if (idx[2] < idx[0]) psb->appendLink(idx[2], idx[0]); @@ -1500,9 +1502,15 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, DerivedMesh* dm, MFace *mface = dm->getTessFaceArray(dm); numpolys = dm->getNumTessFaces(dm); numverts = dm->getNumVerts(dm); - int* index = (int*)dm->getTessFaceDataArray(dm, CD_ORIGINDEX); MTFace *tface = (MTFace *)dm->getTessFaceDataArray(dm, CD_MTFACE); + /* double lookup */ + const int *index_mf_to_mpoly = (const int *)dm->getTessFaceDataArray(dm, CD_ORIGINDEX); + const int *index_mp_to_orig = (const int *)dm->getPolyDataArray(dm, CD_ORIGINDEX); + if ((index_mf_to_mpoly && index_mp_to_orig) == false) { + index_mf_to_mpoly = index_mp_to_orig = NULL; + } + m_shapeType = (polytope) ? PHY_SHAPE_POLYTOPE : PHY_SHAPE_MESH; /* Convert blender geometry into bullet mesh, need these vars for mapping */ @@ -1515,7 +1523,8 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, DerivedMesh* dm, for (int p2=0; p2<numpolys; p2++) { MFace* mf = &mface[p2]; - RAS_Polygon* poly = meshobj->GetPolygon((index)? index[p2]: p2); + const int origi = index_mf_to_mpoly ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, p2) : p2; + RAS_Polygon* poly = meshobj->GetPolygon(origi); // only add polygons that have the collision flag set if (poly->IsCollider()) @@ -1534,7 +1543,8 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, DerivedMesh* dm, for (int p2=0; p2<numpolys; p2++) { MFace* mf = &mface[p2]; - RAS_Polygon* poly= meshobj->GetPolygon((index)? index[p2]: p2); + const int origi = index_mf_to_mpoly ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, p2) : p2; + RAS_Polygon* poly= meshobj->GetPolygon(origi); // only add polygons that have the collisionflag set if (poly->IsCollider()) @@ -1582,7 +1592,8 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, DerivedMesh* dm, for (int p2=0; p2<numpolys; p2++) { MFace* mf = &mface[p2]; - RAS_Polygon* poly= meshobj->GetPolygon((index)? index[p2]: p2); + const int origi = index_mf_to_mpoly ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, p2) : p2; + RAS_Polygon* poly= meshobj->GetPolygon(origi); // only add polygons that have the collision flag set if (poly->IsCollider()) @@ -1619,7 +1630,8 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, DerivedMesh* dm, { MFace* mf = &mface[p2]; MTFace* tf = (tface) ? &tface[p2] : NULL; - RAS_Polygon* poly= meshobj->GetPolygon((index)? index[p2]: p2); + const int origi = index_mf_to_mpoly ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, p2) : p2; + RAS_Polygon* poly= meshobj->GetPolygon(origi); // only add polygons that have the collisionflag set if (poly->IsCollider()) @@ -1645,7 +1657,7 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, DerivedMesh* dm, } // m_polygonIndexArray - *poly_index_pt= (index)? index[p2]: p2; + *poly_index_pt = origi; poly_index_pt++; // the vertex location @@ -1688,7 +1700,7 @@ bool CcdShapeConstructionInfo::SetMesh(RAS_MeshObject* meshobj, DerivedMesh* dm, } // m_polygonIndexArray - *poly_index_pt= (index)? index[p2]: p2; + *poly_index_pt = origi; poly_index_pt++; // the vertex location @@ -1800,7 +1812,13 @@ bool CcdShapeConstructionInfo::UpdateMesh(class KX_GameObject* gameobj, class RA MFace *mface = dm->getTessFaceArray(dm); numpolys = dm->getNumTessFaces(dm); numverts = dm->getNumVerts(dm); - int* index = (int*)dm->getTessFaceDataArray(dm, CD_ORIGINDEX); + + /* double lookup */ + const int *index_mf_to_mpoly = (const int *)dm->getTessFaceDataArray(dm, CD_ORIGINDEX); + const int *index_mp_to_orig = (const int *)dm->getPolyDataArray(dm, CD_ORIGINDEX); + if ((index_mf_to_mpoly && index_mp_to_orig) == false) { + index_mf_to_mpoly = index_mp_to_orig = NULL; + } MFace *mf; MVert *mv; @@ -1856,7 +1874,7 @@ bool CcdShapeConstructionInfo::UpdateMesh(class KX_GameObject* gameobj, class RA { if (tf->mode & TF_DYNAMIC) { - int origi = (index)? index[i]: i; + int origi = index_mf_to_mpoly ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, i) : i; if (mf->v4) { fv_pt= quad_verts; @@ -1915,7 +1933,7 @@ bool CcdShapeConstructionInfo::UpdateMesh(class KX_GameObject* gameobj, class RA } for (mf= mface, i=0; i < numpolys; mf++, i++) { - int origi = (index)? index[i]: i; + int origi = index_mf_to_mpoly ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, i) : i; if (mf->v4) { fv_pt= quad_verts; diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp index e43ddb303e9..687fc116234 100644 --- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp +++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp @@ -2208,10 +2208,29 @@ bool CcdOverlapFilterCallBack::needBroadphaseCollision(btBroadphaseProxy* proxy0 { btCollisionObject *colObj0, *colObj1; CcdPhysicsController *sensorCtrl, *objCtrl; + + KX_GameObject *kxObj0 = KX_GameObject::GetClientObject( + (KX_ClientObjectInfo*) + ((CcdPhysicsController*) + (((btCollisionObject*)proxy0->m_clientObject)->getUserPointer())) + ->getNewClientInfo()); + KX_GameObject *kxObj1 = KX_GameObject::GetClientObject( + (KX_ClientObjectInfo*) + ((CcdPhysicsController*) + (((btCollisionObject*)proxy1->m_clientObject)->getUserPointer())) + ->getNewClientInfo()); + + // First check the filters. Note that this is called during scene + // conversion, so we can't assume the KX_GameObject instances exist. This + // may make some objects erroneously collide on the first frame, but the + // alternative is to have them erroneously miss. bool collides; - // first check the filters collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0; collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask); + if (kxObj0 && kxObj1) { + collides = collides && kxObj0->CheckCollision(kxObj1); + collides = collides && kxObj1->CheckCollision(kxObj0); + } if (!collides) return false; diff --git a/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Erosion2DFilter.h b/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Erosion2DFilter.h index 6319be6ce4a..eaefd5c13fa 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Erosion2DFilter.h +++ b/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Erosion2DFilter.h @@ -32,7 +32,7 @@ #ifndef __RAS_EROSION2DFILTER_H__ #define __RAS_EROSION2DFILTER_H__ -const char * ErosionFragmentShader=STRINGIFY( +const char * ErosionFragmentShader = STRINGIFY( uniform sampler2D bgl_RenderedTexture; uniform vec2 bgl_TextureCoordinateOffset[9]; diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp index dc96e972217..22a700c7d2b 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp @@ -52,7 +52,10 @@ #include "DNA_material_types.h" #include "DNA_scene_types.h" -#include "BKE_DerivedMesh.h" +extern "C"{ + #include "BLI_utildefines.h" + #include "BKE_DerivedMesh.h" +} #ifndef M_PI #define M_PI 3.14159265358979323846 diff --git a/source/gameengine/VideoTexture/FilterSource.h b/source/gameengine/VideoTexture/FilterSource.h index 0e0a3e8d1b9..cb9e22a133d 100644 --- a/source/gameengine/VideoTexture/FilterSource.h +++ b/source/gameengine/VideoTexture/FilterSource.h @@ -142,12 +142,12 @@ 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) + short * size, unsigned int pixSize, unsigned int val) { - // Copy the float value straight away - // The user can retrieve the original float value by using - // 'F' mode in BGL buffer - memcpy(&val, src, sizeof (unsigned int)); + /* Copy the float value straight away + * The user can retrieve the original float value by using + * 'F' mode in BGL buffer */ + memcpy(&val, src, sizeof (unsigned int)); return val; } }; diff --git a/source/gameengine/VideoTexture/ImageViewport.cpp b/source/gameengine/VideoTexture/ImageViewport.cpp index 0836422576f..af44e394fce 100644 --- a/source/gameengine/VideoTexture/ImageViewport.cpp +++ b/source/gameengine/VideoTexture/ImageViewport.cpp @@ -60,7 +60,7 @@ ImageViewport::ImageViewport (void) : m_alpha(false), m_texInit(false) // destructor ImageViewport::~ImageViewport (void) { - delete [] m_viewportImage; + delete [] m_viewportImage; } @@ -127,15 +127,14 @@ void ImageViewport::calcImage (unsigned int texId, double ts) // reset image init(m_capSize[0], m_capSize[1]); // if texture wasn't initialized - if (!m_texInit) - { + if (!m_texInit) { // initialize it loadTexture(texId, m_image, m_size); m_texInit = true; } // if texture can be directly created if (texId != 0 && m_pyfilter == NULL && m_capSize[0] == calcSize(m_capSize[0]) - && m_capSize[1] == calcSize(m_capSize[1]) && !m_flip && !m_zbuff && !m_depth) + && m_capSize[1] == calcSize(m_capSize[1]) && !m_flip && !m_zbuff && !m_depth) { // just copy current viewport to texture glBindTexture(GL_TEXTURE_2D, texId); @@ -144,50 +143,47 @@ void ImageViewport::calcImage (unsigned int texId, double ts) m_avail = false; } // otherwise copy viewport to buffer, if image is not available - else if (!m_avail) - { - if (m_zbuff) - { - // Use read pixels with the depth buffer + else if (!m_avail) { + if (m_zbuff) { + // Use read pixels with the depth buffer // *** misusing m_viewportImage here, but since it has the correct size - // (4 bytes per pixel = size of float) and we just need it to apply + // (4 bytes per pixel = size of float) and we just need it to apply // the filter, it's ok - glReadPixels(m_upLeft[0], m_upLeft[1], (GLsizei)m_capSize[0], (GLsizei)m_capSize[1], - GL_DEPTH_COMPONENT, GL_FLOAT, m_viewportImage); - // filter loaded data - FilterZZZA filt; - filterImage(filt, (float *)m_viewportImage, m_capSize); - } - else - - if (m_depth) - { - // Use read pixels with the depth buffer - // See warning above about m_viewportImage. - glReadPixels(m_upLeft[0], m_upLeft[1], (GLsizei)m_capSize[0], (GLsizei)m_capSize[1], - GL_DEPTH_COMPONENT, GL_FLOAT, m_viewportImage); - // filter loaded data - FilterDEPTH filt; - filterImage(filt, (float *)m_viewportImage, m_capSize); - } - else - - // get frame buffer data - if (m_alpha) - { - glReadPixels(m_upLeft[0], m_upLeft[1], (GLsizei)m_capSize[0], (GLsizei)m_capSize[1], GL_RGBA, - GL_UNSIGNED_BYTE, m_viewportImage); + glReadPixels(m_upLeft[0], m_upLeft[1], (GLsizei)m_capSize[0], (GLsizei)m_capSize[1], + GL_DEPTH_COMPONENT, GL_FLOAT, m_viewportImage); // filter loaded data - FilterRGBA32 filt; - filterImage(filt, m_viewportImage, m_capSize); + FilterZZZA filt; + filterImage(filt, (float *)m_viewportImage, m_capSize); } - else - { - glReadPixels(m_upLeft[0], m_upLeft[1], (GLsizei)m_capSize[0], (GLsizei)m_capSize[1], GL_RGB, - GL_UNSIGNED_BYTE, m_viewportImage); - // filter loaded data - FilterRGB24 filt; - filterImage(filt, m_viewportImage, m_capSize); + else { + + if (m_depth) { + // Use read pixels with the depth buffer + // See warning above about m_viewportImage. + glReadPixels(m_upLeft[0], m_upLeft[1], (GLsizei)m_capSize[0], (GLsizei)m_capSize[1], + GL_DEPTH_COMPONENT, GL_FLOAT, m_viewportImage); + // filter loaded data + FilterDEPTH filt; + filterImage(filt, (float *)m_viewportImage, m_capSize); + } + else { + + // get frame buffer data + if (m_alpha) { + glReadPixels(m_upLeft[0], m_upLeft[1], (GLsizei)m_capSize[0], (GLsizei)m_capSize[1], GL_RGBA, + GL_UNSIGNED_BYTE, m_viewportImage); + // filter loaded data + FilterRGBA32 filt; + filterImage(filt, m_viewportImage, m_capSize); + } + else { + glReadPixels(m_upLeft[0], m_upLeft[1], (GLsizei)m_capSize[0], (GLsizei)m_capSize[1], GL_RGB, + GL_UNSIGNED_BYTE, m_viewportImage); + // filter loaded data + FilterRGB24 filt; + filterImage(filt, m_viewportImage, m_capSize); + } + } } } } diff --git a/source/tests/CMakeLists.txt b/source/tests/CMakeLists.txt index 2bad58699a8..dd84882bea3 100644 --- a/source/tests/CMakeLists.txt +++ b/source/tests/CMakeLists.txt @@ -27,11 +27,11 @@ set(TEST_SRC_DIR ${CMAKE_SOURCE_DIR}/../lib/tests) set(TEST_OUT_DIR ${CMAKE_BINARY_DIR}/tests) # ugh, any better way to do this on testing only? -execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${TEST_OUT_DIR}) +execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${TEST_OUT_DIR}) -#~ if(NOT IS_DIRECTORY ${TEST_SRC_DIR}) -#~ message(FATAL_ERROR "CMake test directory not found!") -#~ endif() +#~ if(NOT IS_DIRECTORY ${TEST_SRC_DIR}) +#~ message(FATAL_ERROR "CMake test directory not found!") +#~ endif() # all calls to blender use this if(APPLE) diff --git a/source/tests/bl_test.py b/source/tests/bl_test.py index cfe91356444..0cb322a21b1 100644 --- a/source/tests/bl_test.py +++ b/source/tests/bl_test.py @@ -145,7 +145,7 @@ def main(): if write_blend is not None: print(" Writing Blend: %s" % write_blend) - bpy.ops.wm.save_mainfile(filepath=write_blend, check_existing=False) + bpy.ops.wm.save_mainfile('EXEC_DEFAULT', filepath=write_blend) print(" Result: '%s'" % str(result)) if not result: |