diff options
author | Bastien Montagne <montagne29@wanadoo.fr> | 2016-11-07 17:46:27 +0300 |
---|---|---|
committer | Bastien Montagne <montagne29@wanadoo.fr> | 2016-11-07 17:46:27 +0300 |
commit | c1ba58c44dd771770037707cd06eb312e015280f (patch) | |
tree | f1a58e6c8a133f6482e9b5eff73ef90bc759de90 | |
parent | 93dbd81796df663598df26119e1e1a5c595be840 (diff) | |
parent | e74e622776a53e4ab5696d4b6fd17638dc2e9210 (diff) |
Merge branch 'master' into blender2.8
Conflicts:
intern/cycles/blender/addon/properties.py
72 files changed, 1364 insertions, 724 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index f3c22d9b717..afc1d9d5872 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -333,7 +333,7 @@ option(WITH_ALEMBIC "Enable Alembic Support" OFF) option(WITH_ALEMBIC_HDF5 "Enable Legacy Alembic Support (not officially supported)" OFF) if(APPLE) - option(WITH_CODEC_QUICKTIME "Enable Quicktime Support" ON) + option(WITH_CODEC_QUICKTIME "Enable Quicktime Support" OFF) endif() # 3D format support @@ -508,6 +508,12 @@ mark_as_advanced(WITH_C11) option(WITH_CXX11 "Build with C++11 standard enabled, for development use only!" ${_cxx11_init}) mark_as_advanced(WITH_CXX11) +# Compiler toolchain +if(CMAKE_COMPILER_IS_GNUCC) + option(WITH_LINKER_GOLD "Use ld.gold linker which is usually faster than ld.bfd" ON) + mark_as_advanced(WITH_LINKER_GOLD) +endif() + # Dependency graph option(WITH_LEGACY_DEPSGRAPH "Build Blender with legacy dependency graph" ON) mark_as_advanced(WITH_LEGACY_DEPSGRAPH) @@ -731,7 +737,7 @@ elseif(WITH_CYCLES OR WITH_OPENIMAGEIO OR WITH_AUDASPACE OR WITH_INTERNATIONAL O # Keep enabled else() # New dependency graph needs either Boost or C++11 for function bindings. - if(NOT USE_CXX11) + if(NOT WITH_CXX11) # Enabled but we don't need it set(WITH_BOOST OFF) endif() diff --git a/build_files/build_environment/install_deps.sh b/build_files/build_environment/install_deps.sh index 8588d235eff..e1f5922272f 100755 --- a/build_files/build_environment/install_deps.sh +++ b/build_files/build_environment/install_deps.sh @@ -4015,9 +4015,6 @@ install_OTHER() { fi if [ "$_do_compile_llvm" = true ]; then - install_packages_DEB libffi-dev - # LLVM can't find the debian ffi header dir - _FFI_INCLUDE_DIR=`dpkg -L libffi-dev | grep -e ".*/ffi.h" | sed -r 's/(.*)\/ffi.h/\1/'` PRINT "" compile_LLVM have_llvm=true @@ -4036,7 +4033,6 @@ install_OTHER() { if [ "$_do_compile_osl" = true ]; then if [ "$have_llvm" = true ]; then - install_packages_DEB flex bison libtbb-dev PRINT "" compile_OSL else @@ -4055,7 +4051,6 @@ install_OTHER() { fi if [ "$_do_compile_osd" = true ]; then - install_packages_DEB flex bison libtbb-dev PRINT "" compile_OSD fi @@ -4072,10 +4067,6 @@ install_OTHER() { fi if [ "$_do_compile_collada" = true ]; then - install_packages_DEB libpcre3-dev - # Find path to libxml shared lib... - _XML2_LIB=`dpkg -L libxml2-dev | grep -e ".*/libxml2.so"` - # No package PRINT "" compile_OpenCOLLADA fi diff --git a/build_files/buildbot/master.cfg b/build_files/buildbot/master.cfg index 8bd23357fc6..6b7191cd57b 100644 --- a/build_files/buildbot/master.cfg +++ b/build_files/buildbot/master.cfg @@ -94,6 +94,7 @@ all_repositories = { r'git://git.blender.org/blender-translations.git': 'blender-translations', r'git://git.blender.org/blender-addons.git': 'blender-addons', r'git://git.blender.org/blender-addons-contrib.git': 'blender-addons-contrib', + r'git://git.blender.org/blender-dev-tools.git': 'blender-dev-tools', r'https://svn.blender.org/svnroot/bf-blender/': 'lib svn', } @@ -128,6 +129,7 @@ def schedule_force_build(name): forcesched.CodebaseParameter(hide=True, codebase="blender-translations"), forcesched.CodebaseParameter(hide=True, codebase="blender-addons"), forcesched.CodebaseParameter(hide=True, codebase="blender-addons-contrib"), + forcesched.CodebaseParameter(hide=True, codebase="blender-dev-tools"), forcesched.CodebaseParameter(hide=True, codebase="lib svn")], properties=[])) @@ -143,6 +145,7 @@ def schedule_build(name, hour, minute=0): "blender-translations": {"repository": "", "branch": "master"}, "blender-addons": {"repository": "", "branch": "master"}, "blender-addons-contrib": {"repository": "", "branch": "master"}, + "blender-dev-tools": {"repository": "", "branch": "master"}, "lib svn": {"repository": "", "branch": "trunk"}}, branch=current_branch, builderNames=[name], @@ -264,7 +267,8 @@ def generic_builder(id, libdir='', branch='', rsync=False): for submodule in ('blender-translations', 'blender-addons', - 'blender-addons-contrib'): + 'blender-addons-contrib', + 'blender-dev-tools'): f.addStep(git_submodule_step(submodule)) f.addStep(git_step(branch)) @@ -299,7 +303,8 @@ add_builder(c, 'linux_glibc219_i686_cmake', '', generic_builder, hour=3) add_builder(c, 'linux_glibc219_x86_64_cmake', '', generic_builder, hour=4) add_builder(c, 'win32_cmake_vc2013', 'windows_vc12', generic_builder, hour=3) add_builder(c, 'win64_cmake_vc2013', 'win64_vc12', generic_builder, hour=4) -add_builder(c, 'win64_cmake_vc2015', 'win64_vc14', generic_builder, hour=5) +add_builder(c, 'win32_cmake_vc2015', 'windows_vc14', generic_builder, hour=5) +add_builder(c, 'win64_cmake_vc2015', 'win64_vc14', generic_builder, hour=6) # STATUS TARGETS # diff --git a/build_files/cmake/platform/platform_unix.cmake b/build_files/cmake/platform/platform_unix.cmake index e33141f8012..62e0caa7c43 100644 --- a/build_files/cmake/platform/platform_unix.cmake +++ b/build_files/cmake/platform/platform_unix.cmake @@ -384,17 +384,18 @@ add_definitions(-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE if(CMAKE_COMPILER_IS_GNUCC) set(PLATFORM_CFLAGS "-pipe -fPIC -funsigned-char -fno-strict-aliasing") - # use ld.gold linker if available, could make optional - execute_process( - COMMAND ${CMAKE_C_COMPILER} -fuse-ld=gold -Wl,--version - ERROR_QUIET OUTPUT_VARIABLE LD_VERSION) - if("${LD_VERSION}" MATCHES "GNU gold") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fuse-ld=gold") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fuse-ld=gold") - else() - message(STATUS "GNU gold linker isn't available, using the default system linker.") + if(WITH_LINKER_GOLD) + execute_process( + COMMAND ${CMAKE_C_COMPILER} -fuse-ld=gold -Wl,--version + ERROR_QUIET OUTPUT_VARIABLE LD_VERSION) + if("${LD_VERSION}" MATCHES "GNU gold") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fuse-ld=gold") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fuse-ld=gold") + else() + message(STATUS "GNU gold linker isn't available, using the default system linker.") + endif() + unset(LD_VERSION) endif() - unset(LD_VERSION) # CLang is the same as GCC for now. elseif(CMAKE_C_COMPILER_ID MATCHES "Clang") diff --git a/intern/cycles/blender/CCL_api.h b/intern/cycles/blender/CCL_api.h index d3a68c4db4f..233ffc8802c 100644 --- a/intern/cycles/blender/CCL_api.h +++ b/intern/cycles/blender/CCL_api.h @@ -21,17 +21,6 @@ extern "C" { #endif -/* returns a list of devices for selection, array is empty identifier - * terminated and must not be freed */ - -typedef struct CCLDeviceInfo { - char identifier[128]; - char name[512]; - int value; -} CCLDeviceInfo; - -CCLDeviceInfo *CCL_compute_device_list(int device_type); - /* create python module _cycles used by addon */ void *CCL_python_module_init(void); diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index 86a0e1cdaf6..3888cdef70e 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -21,7 +21,8 @@ from bpy.props import (BoolProperty, EnumProperty, FloatProperty, IntProperty, - PointerProperty) + PointerProperty, + StringProperty) # enums @@ -122,6 +123,12 @@ enum_volume_interpolation = ( ('CUBIC', "Cubic", "Smoothed high quality interpolation, but slower") ) +enum_device_type = ( + ('CPU', "CPU", "CPU", 0), + ('CUDA', "CUDA", "CUDA", 1), + ('OPENCL', "OpenCL", "OpenCL", 2) + ) + class CyclesRenderSettings(bpy.types.PropertyGroup): @classmethod @@ -1087,6 +1094,103 @@ class CyclesCurveRenderSettings(bpy.types.PropertyGroup): del bpy.types.Scene.cycles_curves +class CyclesDeviceSettings(bpy.types.PropertyGroup): + @classmethod + def register(cls): + cls.id = StringProperty(name="ID") + cls.name = StringProperty(name="Name") + cls.use = BoolProperty(name="Use", default=True) + cls.type = EnumProperty(name="Type", items=enum_device_type, default='CUDA') + + +class CyclesPreferences(bpy.types.AddonPreferences): + bl_idname = __package__ + + def get_device_types(self, context): + import _cycles + has_cuda, has_opencl = _cycles.get_device_types() + list = [('NONE', "None", "Don't use compute device", 0)] + if has_cuda: + list.append(('CUDA', "CUDA", "Use CUDA for GPU acceleration", 1)) + if has_opencl: + list.append(('OPENCL', "OpenCL", "Use OpenCL for GPU acceleration", 2)) + return list + + compute_device_type = EnumProperty( + name="Compute Device Type", + description="Device to use for computation (rendering with Cycles)", + items=get_device_types, + ) + + devices = bpy.props.CollectionProperty(type=CyclesDeviceSettings) + + def get_devices(self): + import _cycles + # Layout of the device tuples: (Name, Type, Internal ID, Persistent ID) + device_list = _cycles.available_devices() + + cuda_devices = [] + opencl_devices = [] + for device in device_list: + if not device[1] in {'CUDA', 'OPENCL'}: + continue + + entry = None + # Try to find existing Device entry + for dev in self.devices: + if dev.id == device[2] and dev.type == device[1]: + entry = dev + break + # Create new entry if no existing one was found + if not entry: + entry = self.devices.add() + entry.id = device[2] + entry.name = device[0] + entry.type = device[1] + + # Sort entries into lists + if entry.type == 'CUDA': + cuda_devices.append(entry) + elif entry.type == 'OPENCL': + opencl_devices.append(entry) + return cuda_devices, opencl_devices + + + def has_active_device(self): + import _cycles + device_list = _cycles.available_devices() + for device in device_list: + if device[1] != self.compute_device_type: + continue + if any(dev.use and dev.id == device[2] for dev in self.devices): + return True + return False + + + def draw_impl(self, layout, context): + layout.label(text="Compute Device:") + layout.row().prop(self, "compute_device_type", expand=True) + + cuda_devices, opencl_devices = self.get_devices() + row = layout.row() + + if cuda_devices: + col = row.column(align=True) + col.label(text="CUDA devices:") + for device in cuda_devices: + col.prop(device, "use", text=device.name, toggle=True) + + if opencl_devices: + col = row.column(align=True) + col.label(text="OpenCL devices:") + for device in opencl_devices: + col.prop(device, "use", text=device.name, toggle=True) + + + def draw(self, context): + self.draw_impl(self.layout, context) + + def register(): bpy.utils.register_class(CyclesRenderSettings) bpy.utils.register_class(CyclesCameraSettings) @@ -1097,6 +1201,8 @@ def register(): bpy.utils.register_class(CyclesMeshSettings) bpy.utils.register_class(CyclesObjectSettings) bpy.utils.register_class(CyclesCurveRenderSettings) + bpy.utils.register_class(CyclesDeviceSettings) + bpy.utils.register_class(CyclesPreferences) def unregister(): @@ -1109,3 +1215,5 @@ def unregister(): bpy.utils.unregister_class(CyclesObjectSettings) bpy.utils.unregister_class(CyclesVisibilitySettings) bpy.utils.unregister_class(CyclesCurveRenderSettings) + bpy.utils.unregister_class(CyclesDeviceSettings) + bpy.utils.unregister_class(CyclesPreferences) diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index 951c1b7c844..2d9785b94d0 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -53,25 +53,26 @@ class CyclesButtonsPanel: return rd.engine in cls.COMPAT_ENGINES +def get_device_type(context): + return context.user_preferences.addons[__package__].preferences.compute_device_type + + def use_cpu(context): cscene = context.scene.cycles - device_type = context.user_preferences.system.compute_device_type - return (device_type == 'NONE' or cscene.device == 'CPU') + return (get_device_type(context) == 'NONE' or cscene.device == 'CPU') def use_opencl(context): cscene = context.scene.cycles - device_type = context.user_preferences.system.compute_device_type - return (device_type == 'OPENCL' and cscene.device == 'GPU') + return (get_device_type(context) == 'OPENCL' and cscene.device == 'GPU') def use_cuda(context): cscene = context.scene.cycles - device_type = context.user_preferences.system.compute_device_type - return (device_type == 'CUDA' and cscene.device == 'GPU') + return (get_device_type(context) == 'CUDA' and cscene.device == 'GPU') def use_branched_path(context): @@ -85,6 +86,14 @@ def use_sample_all_lights(context): return cscene.sample_all_lights_direct or cscene.sample_all_lights_indirect +def show_device_selection(context): + type = get_device_type(context) + if type == 'NETWORK': + return True + if not type in {'CUDA', 'OPENCL'}: + return False + return context.user_preferences.addons[__package__].preferences.has_active_device() + def draw_samples_info(layout, context): cscene = context.scene.cycles @@ -141,7 +150,6 @@ class CyclesRender_PT_sampling(CyclesButtonsPanel, Panel): scene = context.scene cscene = scene.cycles - device_type = context.user_preferences.system.compute_device_type row = layout.row(align=True) row.menu("CYCLES_MT_sampling_presets", text=bpy.types.CYCLES_MT_sampling_presets.bl_label) @@ -150,7 +158,7 @@ class CyclesRender_PT_sampling(CyclesButtonsPanel, Panel): row = layout.row() sub = row.row() - sub.active = device_type != 'OPENCL' or use_cpu(context) + sub.active = get_device_type(context) != 'OPENCL' or use_cpu(context) sub.prop(cscene, "progressive", text="") row.prop(cscene, "use_square_samples") @@ -1542,9 +1550,13 @@ def draw_device(self, context): layout.prop(cscene, "feature_set") - device_type = context.user_preferences.system.compute_device_type - if device_type in {'CUDA', 'OPENCL', 'NETWORK'}: - layout.prop(cscene, "device") + split = layout.split(percentage=1/3) + split.label("Device:") + row = split.row(align=True) + sub = row.split(align=True) + sub.active = show_device_selection(context) + sub.prop(cscene, "device", text="") + row.operator("wm.addon_userpref_show", text="Preferences", icon='PREFERENCES').module = __package__ if engine.with_osl() and use_cpu(context): layout.prop(cscene, "shading_system") diff --git a/intern/cycles/blender/blender_python.cpp b/intern/cycles/blender/blender_python.cpp index a50f5edb1df..438abc49f88 100644 --- a/intern/cycles/blender/blender_python.cpp +++ b/intern/cycles/blender/blender_python.cpp @@ -40,10 +40,6 @@ CCL_NAMESPACE_BEGIN namespace { -/* Device list stored static (used by compute_device_list()). */ -static ccl::vector<CCLDeviceInfo> device_list; -static ccl::DeviceType device_type = DEVICE_NONE; - /* Flag describing whether debug flags were synchronized from scene. */ bool debug_flags_set = false; @@ -195,7 +191,6 @@ static PyObject *exit_func(PyObject * /*self*/, PyObject * /*args*/) ShaderManager::free_memory(); TaskScheduler::free_memory(); Device::free_memory(); - device_list.free_memory(); Py_RETURN_NONE; } @@ -389,7 +384,12 @@ static PyObject *available_devices_func(PyObject * /*self*/, PyObject * /*args*/ for(size_t i = 0; i < devices.size(); i++) { DeviceInfo& device = devices[i]; - PyTuple_SET_ITEM(ret, i, PyUnicode_FromString(device.description.c_str())); + string type_name = Device::string_from_type(device.type); + PyObject *device_tuple = PyTuple_New(3); + PyTuple_SET_ITEM(device_tuple, 0, PyUnicode_FromString(device.description.c_str())); + PyTuple_SET_ITEM(device_tuple, 1, PyUnicode_FromString(type_name.c_str())); + PyTuple_SET_ITEM(device_tuple, 2, PyUnicode_FromString(device.id.c_str())); + PyTuple_SET_ITEM(ret, i, device_tuple); } return ret; @@ -676,6 +676,20 @@ static PyObject *set_resumable_chunks_func(PyObject * /*self*/, PyObject *args) Py_RETURN_NONE; } +static PyObject *get_device_types_func(PyObject * /*self*/, PyObject * /*args*/) +{ + vector<DeviceInfo>& devices = Device::available_devices(); + bool has_cuda = false, has_opencl = false; + for(int i = 0; i < devices.size(); i++) { + has_cuda |= (devices[i].type == DEVICE_CUDA); + has_opencl |= (devices[i].type == DEVICE_OPENCL); + } + PyObject *list = PyTuple_New(2); + PyTuple_SET_ITEM(list, 0, PyBool_FromLong(has_cuda)); + PyTuple_SET_ITEM(list, 1, PyBool_FromLong(has_opencl)); + return list; +} + static PyMethodDef methods[] = { {"init", init_func, METH_VARARGS, ""}, {"exit", exit_func, METH_VARARGS, ""}, @@ -703,6 +717,9 @@ static PyMethodDef methods[] = { /* Resumable render */ {"set_resumable_chunks", set_resumable_chunks_func, METH_VARARGS, ""}, + /* Compute Device selection */ + {"get_device_types", get_device_types_func, METH_VARARGS, ""}, + {NULL, NULL, 0, NULL}, }; @@ -715,47 +732,6 @@ static struct PyModuleDef module = { NULL, NULL, NULL, NULL }; -static CCLDeviceInfo *compute_device_list(DeviceType type) -{ - /* create device list if it's not already done */ - if(type != device_type) { - ccl::vector<DeviceInfo>& devices = ccl::Device::available_devices(); - - device_type = type; - device_list.clear(); - - /* add devices */ - int i = 0; - - foreach(DeviceInfo& info, devices) { - if(info.type == type || - (info.type == DEVICE_MULTI && info.multi_devices[0].type == type)) - { - CCLDeviceInfo cinfo; - - strncpy(cinfo.identifier, info.id.c_str(), sizeof(cinfo.identifier)); - cinfo.identifier[info.id.length()] = '\0'; - - strncpy(cinfo.name, info.description.c_str(), sizeof(cinfo.name)); - cinfo.name[info.description.length()] = '\0'; - - cinfo.value = i++; - - device_list.push_back(cinfo); - } - } - - /* null terminate */ - if(!device_list.empty()) { - CCLDeviceInfo cinfo = {"", "", 0}; - device_list.push_back(cinfo); - } - } - - return (device_list.empty())? NULL: &device_list[0]; -} - - CCL_NAMESPACE_END void *CCL_python_module_init() @@ -794,24 +770,3 @@ void *CCL_python_module_init() return (void*)mod; } - -CCLDeviceInfo *CCL_compute_device_list(int device_type) -{ - ccl::DeviceType type; - switch(device_type) { - case 0: - type = ccl::DEVICE_CUDA; - break; - case 1: - type = ccl::DEVICE_OPENCL; - break; - case 2: - type = ccl::DEVICE_NETWORK; - break; - default: - type = ccl::DEVICE_NONE; - break; - } - return ccl::compute_device_list(type); -} - diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp index 6dc9bc452d8..446c4893fc5 100644 --- a/intern/cycles/blender/blender_sync.cpp +++ b/intern/cycles/blender/blender_sync.cpp @@ -523,7 +523,12 @@ SessionParams BlenderSync::get_session_params(BL::RenderEngine& b_engine, vector<DeviceInfo>& devices = Device::available_devices(); /* device default CPU */ - params.device = devices[0]; + foreach(DeviceInfo& device, devices) { + if(device.type == DEVICE_CPU) { + params.device = device; + break; + } + } if(get_enum(cscene, "device") == 2) { /* find network device */ @@ -532,17 +537,39 @@ SessionParams BlenderSync::get_session_params(BL::RenderEngine& b_engine, params.device = info; } else if(get_enum(cscene, "device") == 1) { - /* find GPU device with given id */ - PointerRNA systemptr = b_userpref.system().ptr; - PropertyRNA *deviceprop = RNA_struct_find_property(&systemptr, "compute_device"); - int device_id = b_userpref.system().compute_device(); + PointerRNA b_preferences; - const char *id; + BL::UserPreferences::addons_iterator b_addon_iter; + for(b_userpref.addons.begin(b_addon_iter); b_addon_iter != b_userpref.addons.end(); ++b_addon_iter) { + if(b_addon_iter->module() == "cycles") { + b_preferences = b_addon_iter->preferences().ptr; + break; + } + } - if(RNA_property_enum_identifier(NULL, &systemptr, deviceprop, device_id, &id)) { - foreach(DeviceInfo& info, devices) - if(info.id == id) - params.device = info; + int compute_device = get_enum(b_preferences, "compute_device_type"); + + if(compute_device != 0) { + vector<DeviceInfo> used_devices; + RNA_BEGIN(&b_preferences, device, "devices") { + if(get_enum(device, "type") == compute_device && get_boolean(device, "use")) { + string id = get_string(device, "id"); + foreach(DeviceInfo& info, devices) { + if(info.id == id) { + used_devices.push_back(info); + break; + } + } + } + } RNA_END + + if(used_devices.size() == 1) { + params.device = used_devices[0]; + } + else if(used_devices.size() > 1) { + params.device = Device::get_multi_device(used_devices); + } + /* Else keep using the CPU device that was set before. */ } } diff --git a/intern/cycles/cmake/external_libs.cmake b/intern/cycles/cmake/external_libs.cmake index 616dd940801..403a0540963 100644 --- a/intern/cycles/cmake/external_libs.cmake +++ b/intern/cycles/cmake/external_libs.cmake @@ -44,6 +44,10 @@ if(WITH_CYCLES_CUDA_BINARIES OR NOT WITH_CUDA_DYNLOAD) else() message(STATUS "CUDA compiler not found, disabling WITH_CYCLES_CUDA_BINARIES") set(WITH_CYCLES_CUDA_BINARIES OFF) + if(NOT WITH_CUDA_DYNLOAD) + message(STATUS "Additionally falling back to dynamic CUDA load") + set(WITH_CUDA_DYNLOAD ON) + endif() endif() endif() diff --git a/intern/cycles/device/device.cpp b/intern/cycles/device/device.cpp index 909ec7a6d60..ff9387b0a8a 100644 --- a/intern/cycles/device/device.cpp +++ b/intern/cycles/device/device.cpp @@ -258,33 +258,33 @@ Device *Device::create(DeviceInfo& info, Stats &stats, bool background) DeviceType Device::type_from_string(const char *name) { - if(strcmp(name, "cpu") == 0) + if(strcmp(name, "CPU") == 0) return DEVICE_CPU; - else if(strcmp(name, "cuda") == 0) + else if(strcmp(name, "CUDA") == 0) return DEVICE_CUDA; - else if(strcmp(name, "opencl") == 0) + else if(strcmp(name, "OPENCL") == 0) return DEVICE_OPENCL; - else if(strcmp(name, "network") == 0) + else if(strcmp(name, "NETWORK") == 0) return DEVICE_NETWORK; - else if(strcmp(name, "multi") == 0) + else if(strcmp(name, "MULTI") == 0) return DEVICE_MULTI; - + return DEVICE_NONE; } string Device::string_from_type(DeviceType type) { if(type == DEVICE_CPU) - return "cpu"; + return "CPU"; else if(type == DEVICE_CUDA) - return "cuda"; + return "CUDA"; else if(type == DEVICE_OPENCL) - return "opencl"; + return "OPENCL"; else if(type == DEVICE_NETWORK) - return "network"; + return "NETWORK"; else if(type == DEVICE_MULTI) - return "multi"; - + return "MULTI"; + return ""; } @@ -307,9 +307,6 @@ vector<DeviceType>& Device::available_types() #ifdef WITH_NETWORK types.push_back(DEVICE_NETWORK); #endif -#ifdef WITH_MULTI - types.push_back(DEVICE_MULTI); -#endif need_types_update = false; } @@ -331,10 +328,6 @@ vector<DeviceInfo>& Device::available_devices() device_opencl_info(devices); #endif -#ifdef WITH_MULTI - device_multi_info(devices); -#endif - device_cpu_info(devices); #ifdef WITH_NETWORK @@ -368,6 +361,29 @@ string Device::device_capabilities() return capabilities; } +DeviceInfo Device::get_multi_device(vector<DeviceInfo> subdevices) +{ + assert(subdevices.size() > 1); + + DeviceInfo info; + info.type = DEVICE_MULTI; + info.id = "MULTI"; + info.description = "Multi Device"; + info.multi_devices = subdevices; + info.num = 0; + + info.has_bindless_textures = true; + info.pack_images = false; + foreach(DeviceInfo &device, subdevices) { + assert(device.type == info.multi_devices[0].type); + + info.pack_images |= device.pack_images; + info.has_bindless_textures &= device.has_bindless_textures; + } + + return info; +} + void Device::tag_update() { need_types_update = true; diff --git a/intern/cycles/device/device.h b/intern/cycles/device/device.h index 77dc1fa9713..b9bdffa2618 100644 --- a/intern/cycles/device/device.h +++ b/intern/cycles/device/device.h @@ -49,7 +49,7 @@ class DeviceInfo { public: DeviceType type; string description; - string id; + string id; /* used for user preferences, should stay fixed with changing hardware config */ int num; bool display_device; bool advanced_shading; @@ -69,6 +69,12 @@ public: has_bindless_textures = false; use_split_kernel = false; } + + bool operator==(const DeviceInfo &info) { + /* Multiple Devices with the same ID would be very bad. */ + assert(id != info.id || (type == info.type && num == info.num && description == info.description)); + return id == info.id; + } }; class DeviceRequestedFeatures { @@ -282,6 +288,7 @@ public: static vector<DeviceType>& available_types(); static vector<DeviceInfo>& available_devices(); static string device_capabilities(); + static DeviceInfo get_multi_device(vector<DeviceInfo> subdevices); /* Tag devices lists for update. */ static void tag_update(); diff --git a/intern/cycles/device/device_cuda.cpp b/intern/cycles/device/device_cuda.cpp index 7f8a0bf2f43..a4818aa3b8d 100644 --- a/intern/cycles/device/device_cuda.cpp +++ b/intern/cycles/device/device_cuda.cpp @@ -14,6 +14,7 @@ * limitations under the License. */ +#include <climits> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -213,7 +214,8 @@ public: return; int major, minor; - cuDeviceComputeCapability(&major, &minor, cuDevId); + cuDeviceGetAttribute(&major, CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MAJOR, cuDevId); + cuDeviceGetAttribute(&minor, CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MINOR, cuDevId); cuDevArchitecture = major*100 + minor*10; cuda_pop_context(); @@ -233,7 +235,8 @@ public: bool support_device(const DeviceRequestedFeatures& /*requested_features*/) { int major, minor; - cuDeviceComputeCapability(&major, &minor, cuDevId); + cuDeviceGetAttribute(&major, CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MAJOR, cuDevId); + cuDeviceGetAttribute(&minor, CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MINOR, cuDevId); /* We only support sm_20 and above */ if(major < 2) { @@ -315,7 +318,8 @@ public: { /* Compute cubin name. */ int major, minor; - cuDeviceComputeCapability(&major, &minor, cuDevId); + cuDeviceGetAttribute(&major, CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MAJOR, cuDevId); + cuDeviceGetAttribute(&minor, CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MINOR, cuDevId); /* Attempt to use kernel provided with Blender. */ if(!use_adaptive_compilation()) { @@ -1394,8 +1398,8 @@ void device_cuda_info(vector<DeviceInfo>& devices) if(cuDeviceGetName(name, 256, num) != CUDA_SUCCESS) continue; - int major, minor; - cuDeviceComputeCapability(&major, &minor, num); + int major; + cuDeviceGetAttribute(&major, CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MAJOR, num); if(major < 2) { continue; } @@ -1404,13 +1408,18 @@ void device_cuda_info(vector<DeviceInfo>& devices) info.type = DEVICE_CUDA; info.description = string(name); - info.id = string_printf("CUDA_%d", num); info.num = num; info.advanced_shading = (major >= 2); info.has_bindless_textures = (major >= 3); info.pack_images = false; + int pci_location[3] = {0, 0, 0}; + cuDeviceGetAttribute(&pci_location[0], CU_DEVICE_ATTRIBUTE_PCI_DOMAIN_ID, num); + cuDeviceGetAttribute(&pci_location[1], CU_DEVICE_ATTRIBUTE_PCI_BUS_ID, num); + cuDeviceGetAttribute(&pci_location[2], CU_DEVICE_ATTRIBUTE_PCI_DEVICE_ID, num); + info.id = string_printf("CUDA_%s_%04x:%02x:%02x", name, pci_location[0], pci_location[1], pci_location[2]); + /* if device has a kernel timeout, assume it is used for display */ if(cuDeviceGetAttribute(&attr, CU_DEVICE_ATTRIBUTE_KERNEL_EXEC_TIMEOUT, num) == CUDA_SUCCESS && attr == 1) { info.description += " (Display)"; diff --git a/intern/cycles/device/device_intern.h b/intern/cycles/device/device_intern.h index 47584ae6d22..de487649045 100644 --- a/intern/cycles/device/device_intern.h +++ b/intern/cycles/device/device_intern.h @@ -33,7 +33,6 @@ void device_cpu_info(vector<DeviceInfo>& devices); void device_opencl_info(vector<DeviceInfo>& devices); void device_cuda_info(vector<DeviceInfo>& devices); void device_network_info(vector<DeviceInfo>& devices); -void device_multi_info(vector<DeviceInfo>& devices); string device_cpu_capabilities(void); string device_opencl_capabilities(void); diff --git a/intern/cycles/device/device_multi.cpp b/intern/cycles/device/device_multi.cpp index ef257358b22..48fd159d508 100644 --- a/intern/cycles/device/device_multi.cpp +++ b/intern/cycles/device/device_multi.cpp @@ -350,120 +350,5 @@ Device *device_multi_create(DeviceInfo& info, Stats &stats, bool background) return new MultiDevice(info, stats, background); } -static bool device_multi_add(vector<DeviceInfo>& devices, DeviceType type, bool with_display, bool with_advanced_shading, const char *id_fmt, int num) -{ - DeviceInfo info; - - /* create map to find duplicate descriptions */ - map<string, int> dupli_map; - map<string, int>::iterator dt; - int num_added = 0, num_display = 0; - - info.advanced_shading = with_advanced_shading; - info.pack_images = false; - info.has_bindless_textures = true; - - foreach(DeviceInfo& subinfo, devices) { - if(subinfo.type == type) { - if(subinfo.advanced_shading != info.advanced_shading) - continue; - if(subinfo.display_device) { - if(with_display) - num_display++; - else - continue; - } - - string key = subinfo.description; - - if(dupli_map.find(key) == dupli_map.end()) - dupli_map[key] = 1; - else - dupli_map[key]++; - - info.multi_devices.push_back(subinfo); - if(subinfo.display_device) - info.display_device = true; - info.pack_images = info.pack_images || subinfo.pack_images; - info.has_bindless_textures = info.has_bindless_textures && subinfo.has_bindless_textures; - num_added++; - } - } - - if(num_added <= 1 || (with_display && num_display == 0)) - return false; - - /* generate string */ - stringstream desc; - vector<string> last_tokens; - bool first = true; - - for(dt = dupli_map.begin(); dt != dupli_map.end(); dt++) { - if(!first) desc << " + "; - first = false; - - /* get name and count */ - string name = dt->first; - int count = dt->second; - - /* strip common prefixes */ - vector<string> tokens; - string_split(tokens, dt->first); - - if(tokens.size() > 1) { - int i; - - for(i = 0; i < tokens.size() && i < last_tokens.size(); i++) - if(tokens[i] != last_tokens[i]) - break; - - name = ""; - for(; i < tokens.size(); i++) { - name += tokens[i]; - if(i != tokens.size() - 1) - name += " "; - } - } - - last_tokens = tokens; - - /* add */ - if(count > 1) - desc << name << " (" << count << "x)"; - else - desc << name; - } - - /* add info */ - info.type = DEVICE_MULTI; - info.description = desc.str(); - info.id = string_printf(id_fmt, num); - info.display_device = with_display; - info.num = 0; - - if(with_display) - devices.push_back(info); - else - devices.insert(devices.begin(), info); - - return true; -} - -void device_multi_info(vector<DeviceInfo>& devices) -{ - int num = 0; - - if(!device_multi_add(devices, DEVICE_CUDA, false, true, "CUDA_MULTI_%d", num++)) - device_multi_add(devices, DEVICE_CUDA, false, false, "CUDA_MULTI_%d", num++); - if(!device_multi_add(devices, DEVICE_CUDA, true, true, "CUDA_MULTI_%d", num++)) - device_multi_add(devices, DEVICE_CUDA, true, false, "CUDA_MULTI_%d", num++); - - num = 0; - if(!device_multi_add(devices, DEVICE_OPENCL, false, true, "OPENCL_MULTI_%d", num++)) - device_multi_add(devices, DEVICE_OPENCL, false, false, "OPENCL_MULTI_%d", num++); - if(!device_multi_add(devices, DEVICE_OPENCL, true, true, "OPENCL_MULTI_%d", num++)) - device_multi_add(devices, DEVICE_OPENCL, true, false, "OPENCL_MULTI_%d", num++); -} - CCL_NAMESPACE_END diff --git a/intern/cycles/device/device_opencl.cpp b/intern/cycles/device/device_opencl.cpp index 45cf6b074e9..ba94c592a5f 100644 --- a/intern/cycles/device/device_opencl.cpp +++ b/intern/cycles/device/device_opencl.cpp @@ -83,17 +83,22 @@ void device_opencl_info(vector<DeviceInfo>& devices) const string& platform_name = platform_device.platform_name; const cl_device_type device_type = platform_device.device_type; const string& device_name = platform_device.device_name; + string hardware_id = platform_device.hardware_id; + if(hardware_id == "") { + hardware_id = string_printf("ID_%d", num_devices); + } + DeviceInfo info; info.type = DEVICE_OPENCL; info.description = string_remove_trademark(string(device_name)); info.num = num_devices; - info.id = string_printf("OPENCL_%d", info.num); /* We don't know if it's used for display, but assume it is. */ info.display_device = true; info.advanced_shading = OpenCLInfo::kernel_use_advanced_shading(platform_name); info.pack_images = true; info.use_split_kernel = OpenCLInfo::kernel_use_split(platform_name, device_type); + info.id = string("OPENCL_") + platform_name + "_" + device_name + "_" + hardware_id; devices.push_back(info); num_devices++; } diff --git a/intern/cycles/device/opencl/opencl.h b/intern/cycles/device/opencl/opencl.h index 30a35acbb2a..054ac9014f0 100644 --- a/intern/cycles/device/opencl/opencl.h +++ b/intern/cycles/device/opencl/opencl.h @@ -55,17 +55,20 @@ struct OpenCLPlatformDevice { const string& platform_name, cl_device_id device_id, cl_device_type device_type, - const string& device_name) + const string& device_name, + const string& hardware_id) : platform_id(platform_id), platform_name(platform_name), device_id(device_id), device_type(device_type), - device_name(device_name) {} + device_name(device_name), + hardware_id(hardware_id) {} cl_platform_id platform_id; string platform_name; cl_device_id device_id; cl_device_type device_type; string device_name; + string hardware_id; }; /* Contains all static OpenCL helper functions. */ @@ -83,6 +86,8 @@ public: string *error = NULL); static bool device_version_check(cl_device_id device, string *error = NULL); + static string get_hardware_id(string platform_name, + cl_device_id device_id); static void get_usable_devices(vector<OpenCLPlatformDevice> *usable_devices, bool force_all = false); }; diff --git a/intern/cycles/device/opencl/opencl_util.cpp b/intern/cycles/device/opencl/opencl_util.cpp index e425ae8e2e8..36eb70b8c85 100644 --- a/intern/cycles/device/opencl/opencl_util.cpp +++ b/intern/cycles/device/opencl/opencl_util.cpp @@ -661,6 +661,27 @@ bool OpenCLInfo::device_version_check(cl_device_id device, return true; } +string OpenCLInfo::get_hardware_id(string platform_name, cl_device_id device_id) +{ + if(platform_name == "AMD Accelerated Parallel Processing" || platform_name == "Apple") { + /* Use cl_amd_device_topology extension. */ + cl_char topology[24]; + if(clGetDeviceInfo(device_id, 0x4037, sizeof(topology), topology, NULL) == CL_SUCCESS && topology[0] == 1) { + return string_printf("%02x:%02x.%01x", topology[21], topology[22], topology[23]); + } + } + else if(platform_name == "NVIDIA CUDA") { + /* Use two undocumented options of the cl_nv_device_attribute_query extension. */ + cl_int bus_id, slot_id; + if(clGetDeviceInfo(device_id, 0x4008, sizeof(cl_int), &bus_id, NULL) == CL_SUCCESS && + clGetDeviceInfo(device_id, 0x4009, sizeof(cl_int), &slot_id, NULL) == CL_SUCCESS) { + return string_printf("%02x:%02x.%01x", bus_id, slot_id>>3, slot_id & 0x7); + } + } + /* No general way to get a hardware ID from OpenCL => give up. */ + return ""; +} + void OpenCLInfo::get_usable_devices(vector<OpenCLPlatformDevice> *usable_devices, bool force_all) { @@ -773,11 +794,13 @@ void OpenCLInfo::get_usable_devices(vector<OpenCLPlatformDevice> *usable_devices continue; } FIRST_VLOG(2) << "Adding new device " << device_name << "."; + string hardware_id = get_hardware_id(platform_name, device_id); usable_devices->push_back(OpenCLPlatformDevice(platform_id, platform_name, device_id, device_type, - device_name)); + device_name, + hardware_id)); } else { FIRST_VLOG(2) << "Ignoring device " << device_name diff --git a/intern/cycles/kernel/geom/geom_object.h b/intern/cycles/kernel/geom/geom_object.h index 6b42f66b0d5..9f0fe032ba4 100644 --- a/intern/cycles/kernel/geom/geom_object.h +++ b/intern/cycles/kernel/geom/geom_object.h @@ -162,10 +162,14 @@ ccl_device_inline void object_inverse_position_transform(KernelGlobals *kg, cons ccl_device_inline void object_inverse_normal_transform(KernelGlobals *kg, const ShaderData *sd, float3 *N) { #ifdef __OBJECT_MOTION__ - *N = normalize(transform_direction_transposed_auto(&ccl_fetch(sd, ob_tfm), *N)); + if((ccl_fetch(sd, object) != OBJECT_NONE) || (ccl_fetch(sd, type) == PRIMITIVE_LAMP)) { + *N = normalize(transform_direction_transposed_auto(&ccl_fetch(sd, ob_tfm), *N)); + } #else - Transform tfm = object_fetch_transform(kg, ccl_fetch(sd, object), OBJECT_TRANSFORM); - *N = normalize(transform_direction_transposed(&tfm, *N)); + if(ccl_fetch(sd, object) != OBJECT_NONE) { + Transform tfm = object_fetch_transform(kg, ccl_fetch(sd, object), OBJECT_TRANSFORM); + *N = normalize(transform_direction_transposed(&tfm, *N)); + } #endif } diff --git a/intern/cycles/kernel/kernel_random.h b/intern/cycles/kernel/kernel_random.h index 2372b07d974..2b767da5041 100644 --- a/intern/cycles/kernel/kernel_random.h +++ b/intern/cycles/kernel/kernel_random.h @@ -301,7 +301,7 @@ ccl_device_inline void path_branched_rng_2D(KernelGlobals *kg, ccl_addr_space RN } /* Utitility functions to get light termination value, since it might not be needed in many cases. */ -ccl_device_inline float path_state_rng_light_termination(KernelGlobals *kg, ccl_addr_space RNG *rng, const PathState *state) +ccl_device_inline float path_state_rng_light_termination(KernelGlobals *kg, ccl_addr_space RNG *rng, const ccl_addr_space PathState *state) { if(kernel_data.integrator.light_inv_rr_threshold > 0.0f) { return path_state_rng_1D_for_decision(kg, rng, state, PRNG_LIGHT_TERMINATE); diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h index b4b980c4e90..c1b3153d8fe 100644 --- a/intern/cycles/kernel/kernel_shader.h +++ b/intern/cycles/kernel/kernel_shader.h @@ -276,16 +276,13 @@ ccl_device_inline void shader_setup_from_sample(KernelGlobals *kg, #ifdef __OBJECT_MOTION__ shader_setup_object_transforms(kg, sd, time); -#endif + ccl_fetch(sd, time) = time; } else if(lamp != LAMP_NONE) { ccl_fetch(sd, ob_tfm) = lamp_fetch_transform(kg, lamp, false); ccl_fetch(sd, ob_itfm) = lamp_fetch_transform(kg, lamp, true); - } - -#ifdef __OBJECT_MOTION__ - ccl_fetch(sd, time) = time; #endif + } /* transform into world space */ if(object_space) { diff --git a/intern/cycles/kernel/svm/svm_image.h b/intern/cycles/kernel/svm/svm_image.h index 9606064492e..2afdf61b476 100644 --- a/intern/cycles/kernel/svm/svm_image.h +++ b/intern/cycles/kernel/svm/svm_image.h @@ -241,8 +241,7 @@ ccl_device void svm_node_tex_image_box(KernelGlobals *kg, ShaderData *sd, float float3 N = ccl_fetch(sd, N); N = ccl_fetch(sd, N); - if(ccl_fetch(sd, object) != OBJECT_NONE) - object_inverse_normal_transform(kg, sd, &N); + object_inverse_normal_transform(kg, sd, &N); /* project from direction vector to barycentric coordinates in triangles */ N.x = fabsf(N.x); diff --git a/intern/cycles/kernel/svm/svm_tex_coord.h b/intern/cycles/kernel/svm/svm_tex_coord.h index 6c3394adbce..c0b01262212 100644 --- a/intern/cycles/kernel/svm/svm_tex_coord.h +++ b/intern/cycles/kernel/svm/svm_tex_coord.h @@ -49,8 +49,7 @@ ccl_device void svm_node_tex_coord(KernelGlobals *kg, } case NODE_TEXCO_NORMAL: { data = ccl_fetch(sd, N); - if((ccl_fetch(sd, object) != OBJECT_NONE) || (ccl_fetch(sd, type) == PRIMITIVE_LAMP)) - object_inverse_normal_transform(kg, sd, &data); + object_inverse_normal_transform(kg, sd, &data); break; } case NODE_TEXCO_CAMERA: { @@ -131,8 +130,7 @@ ccl_device void svm_node_tex_coord_bump_dx(KernelGlobals *kg, } case NODE_TEXCO_NORMAL: { data = ccl_fetch(sd, N); - if((ccl_fetch(sd, object) != OBJECT_NONE) || (ccl_fetch(sd, type) == PRIMITIVE_LAMP)) - object_inverse_normal_transform(kg, sd, &data); + object_inverse_normal_transform(kg, sd, &data); break; } case NODE_TEXCO_CAMERA: { @@ -216,8 +214,7 @@ ccl_device void svm_node_tex_coord_bump_dy(KernelGlobals *kg, } case NODE_TEXCO_NORMAL: { data = ccl_fetch(sd, N); - if((ccl_fetch(sd, object) != OBJECT_NONE) || (ccl_fetch(sd, type) == PRIMITIVE_LAMP)) - object_inverse_normal_transform(kg, sd, &data); + object_inverse_normal_transform(kg, sd, &data); break; } case NODE_TEXCO_CAMERA: { diff --git a/intern/cycles/render/light.cpp b/intern/cycles/render/light.cpp index 777f3229ce6..c43d646f515 100644 --- a/intern/cycles/render/light.cpp +++ b/intern/cycles/render/light.cpp @@ -43,8 +43,8 @@ static void shade_background_pixels(Device *device, DeviceScene *dscene, int res for(int y = 0; y < height; y++) { for(int x = 0; x < width; x++) { - float u = x/(float)width; - float v = y/(float)height; + float u = (x + 0.5f)/width; + float v = (y + 0.5f)/height; uint4 in = make_uint4(__float_as_int(u), __float_as_int(v), 0, 0); d_input_data[x + y*width] = in; diff --git a/intern/cycles/render/session.h b/intern/cycles/render/session.h index 8bff0f9ed15..1db4692e171 100644 --- a/intern/cycles/render/session.h +++ b/intern/cycles/render/session.h @@ -89,8 +89,7 @@ public: } bool modified(const SessionParams& params) - { return !(device.type == params.device.type - && device.id == params.device.id + { return !(device == params.device && background == params.background && progressive_refine == params.progressive_refine && output_path == params.output_path diff --git a/intern/libmv/libmv/simple_pipeline/modal_solver_test.cc b/intern/libmv/libmv/simple_pipeline/modal_solver_test.cc index 8b87acd95bb..b4cae8defb2 100644 --- a/intern/libmv/libmv/simple_pipeline/modal_solver_test.cc +++ b/intern/libmv/libmv/simple_pipeline/modal_solver_test.cc @@ -65,9 +65,9 @@ TEST(ModalSolver, SyntheticCubeSceneMotion) { NULL); Mat3 expected_rotation; - expected_rotation << 0.98215101299251, 0.17798357184544, 0.06083778292258, - -0.16875286001759, 0.97665299913606, -0.13293378620359, - -0.08307743323957, 0.12029450291547, 0.98925596922871; + expected_rotation << 0.98215101743472, 0.17798354937546, 0.06083777694542, + -0.16875283983360, 0.97665300495333, -0.13293376908719, + -0.08307742172243, 0.12029448893171, 0.98925597189636; Mat3 &first_camera_R = reconstruction.CameraForImage(1)->R; Mat3 &second_camera_R = reconstruction.CameraForImage(2)->R; @@ -4,6 +4,11 @@ REM This is for users who like to configure & build Blender with a single comman setlocal ENABLEEXTENSIONS set BLENDER_DIR=%~dp0 +set BLENDER_DIR_NOSPACES=%BLENDER_DIR: =% +if not "%BLENDER_DIR%"=="%BLENDER_DIR_NOSPACES%" ( + echo There are spaces detected in the build path "%BLENDER_DIR%", this is currently not supported, exiting.... + goto EOF +) set BUILD_DIR=%BLENDER_DIR%..\build_windows set BUILD_TYPE=Release rem reset all variables so they do not get accidentally get carried over from previous builds diff --git a/release/scripts/startup/bl_operators/mesh.py b/release/scripts/startup/bl_operators/mesh.py index be74f8dbc0e..58eab5436e6 100644 --- a/release/scripts/startup/bl_operators/mesh.py +++ b/release/scripts/startup/bl_operators/mesh.py @@ -198,3 +198,53 @@ class MeshSelectPrev(Operator): bmesh.update_edit_mesh(me, False) return {'FINISHED'} + + +# XXX This is hackish (going forth and back from Object mode...), to be redone once we have proper support of +# custom normals in BMesh/edit mode. +class MehsSetNormalsFromFaces(Operator): + """Set the custom vertex normals from the selected faces ones""" + bl_idname = "mesh.set_normals_from_faces" + bl_label = "Set Normals From Faces" + bl_options = {'REGISTER', 'UNDO'} + + @classmethod + def poll(cls, context): + return (context.mode == 'EDIT_MESH' and context.edit_object.data.polygons) + + def execute(self, context): + import mathutils + + bpy.ops.object.mode_set(mode='OBJECT') + obj = context.active_object + me = obj.data + + v2nors = {} + for p in me.polygons: + if not p.select: + continue + for lidx, vidx in zip(p.loop_indices, p.vertices): + assert(me.loops[lidx].vertex_index == vidx) + v2nors.setdefault(vidx, []).append(p.normal) + + for nors in v2nors.values(): + nors[:] = [sum(nors, mathutils.Vector((0, 0, 0))).normalized()] + + if not me.has_custom_normals: + me.create_normals_split() + me.calc_normals_split() + + normals = [] + for l in me.loops: + nor = v2nors.get(l.vertex_index, [None])[0] + if nor is None: + nor = l.normal + normals.append(nor.to_tuple()) + + me.normals_split_custom_set(normals) + + me.free_normals_split() + bpy.ops.object.mode_set(mode='EDIT') + + return {'FINISHED'} + diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py index 1c97d213e05..343fcdb0d22 100644 --- a/release/scripts/startup/bl_operators/wm.py +++ b/release/scripts/startup/bl_operators/wm.py @@ -2163,3 +2163,32 @@ class WM_OT_addon_expand(Operator): info["show_expanded"] = not info["show_expanded"] return {'FINISHED'} + +class WM_OT_addon_userpref_show(Operator): + "Show add-on user preferences" + bl_idname = "wm.addon_userpref_show" + bl_label = "" + bl_options = {'INTERNAL'} + + module = StringProperty( + name="Module", + description="Module name of the add-on to expand", + ) + + def execute(self, context): + import addon_utils + + module_name = self.module + + modules = addon_utils.modules(refresh=False) + mod = addon_utils.addons_fake_modules.get(module_name) + if mod is not None: + info = addon_utils.module_bl_info(mod) + info["show_expanded"] = True + + bpy.context.user_preferences.active_section = 'ADDONS' + context.window_manager.addon_filter = 'All' + context.window_manager.addon_search = info["name"] + bpy.ops.screen.userpref_show('INVOKE_DEFAULT') + + return {'FINISHED'} diff --git a/release/scripts/startup/bl_ui/properties_physics_rigidbody_constraint.py b/release/scripts/startup/bl_ui/properties_physics_rigidbody_constraint.py index 38c97746f4a..9d4f51b256b 100644 --- a/release/scripts/startup/bl_ui/properties_physics_rigidbody_constraint.py +++ b/release/scripts/startup/bl_ui/properties_physics_rigidbody_constraint.py @@ -205,30 +205,60 @@ class PHYSICS_PT_rigid_body_constraint(PHYSICS_PT_rigidbody_constraint_panel, Pa row = col.row(align=True) sub = row.row(align=True) - sub.scale_x = 0.1 - sub.prop(rbc, "use_spring_x", toggle=True, text="X") + sub.scale_x = 0.5 + sub.prop(rbc, "use_spring_x", toggle=True, text="X Axis") sub = row.row(align=True) sub.active = rbc.use_spring_x sub.prop(rbc, "spring_stiffness_x", text="Stiffness") - sub.prop(rbc, "spring_damping_x") + sub.prop(rbc, "spring_damping_x", text="Damping") row = col.row(align=True) sub = row.row(align=True) - sub.scale_x = 0.1 - sub.prop(rbc, "use_spring_y", toggle=True, text="Y") + sub.scale_x = 0.5 + sub.prop(rbc, "use_spring_y", toggle=True, text="Y Axis") sub = row.row(align=True) sub.active = rbc.use_spring_y sub.prop(rbc, "spring_stiffness_y", text="Stiffness") - sub.prop(rbc, "spring_damping_y") + sub.prop(rbc, "spring_damping_y", text="Damping") row = col.row(align=True) sub = row.row(align=True) - sub.scale_x = 0.1 - sub.prop(rbc, "use_spring_z", toggle=True, text="Z") + sub.scale_x = 0.5 + sub.prop(rbc, "use_spring_z", toggle=True, text="Z Axis") sub = row.row(align=True) sub.active = rbc.use_spring_z sub.prop(rbc, "spring_stiffness_z", text="Stiffness") - sub.prop(rbc, "spring_damping_z") + sub.prop(rbc, "spring_damping_z", text="Damping") + + col = layout.column(align=True) + + row = col.row(align=True) + sub = row.row(align=True) + sub.scale_x = 0.5 + sub.prop(rbc, "use_spring_ang_x", toggle=True, text="X Angle") + sub = row.row(align=True) + sub.active = rbc.use_spring_ang_x + sub.prop(rbc, "spring_stiffness_ang_x", text="Stiffness") + sub.prop(rbc, "spring_damping_ang_x", text="Damping") + + row = col.row(align=True) + sub = row.row(align=True) + sub.scale_x = 0.5 + sub.prop(rbc, "use_spring_ang_y", toggle=True, text="Y Angle") + sub = row.row(align=True) + sub.active = rbc.use_spring_ang_y + sub.prop(rbc, "spring_stiffness_ang_y", text="Stiffness") + sub.prop(rbc, "spring_damping_ang_y", text="Damping") + + row = col.row(align=True) + sub = row.row(align=True) + sub.scale_x = 0.5 + sub.prop(rbc, "use_spring_ang_z", toggle=True, text="Z Angle") + sub = row.row(align=True) + sub.active = rbc.use_spring_ang_z + sub.prop(rbc, "spring_stiffness_ang_z", text="Stiffness") + sub.prop(rbc, "spring_damping_ang_z", text="Damping") + if __name__ == "__main__": # only for live edit. bpy.utils.register_module(__name__) diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py index ab51e703e37..1cbc0410829 100644 --- a/release/scripts/startup/bl_ui/space_userpref.py +++ b/release/scripts/startup/bl_ui/space_userpref.py @@ -428,13 +428,6 @@ class USERPREF_PT_system(Panel): col.separator() - if hasattr(system, "compute_device_type"): - col.label(text="Compute Device:") - col.row().prop(system, "compute_device_type", expand=True) - sub = col.row() - sub.active = system.compute_device_type != 'CPU' - sub.prop(system, "compute_device", text="") - if hasattr(system, "opensubdiv_compute_type"): col.label(text="OpenSubdiv compute:") col.row().prop(system, "opensubdiv_compute_type", text="") diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py index 71f81483aac..9d66ab55a0d 100644 --- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -431,6 +431,7 @@ class VIEW3D_PT_tools_shading(View3DPanel, Panel): col.label(text="Normals:") col.operator("mesh.normals_make_consistent", text="Recalculate") col.operator("mesh.flip_normals", text="Flip Direction") + col.operator("mesh.set_normals_from_faces", text="Set From Faces") class VIEW3D_PT_tools_uvs(View3DPanel, Panel): diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h index c2323100205..78d6f6c7cb9 100644 --- a/source/blender/blenkernel/BKE_armature.h +++ b/source/blender/blenkernel/BKE_armature.h @@ -97,6 +97,7 @@ void BKE_armature_where_is(struct bArmature *arm); void BKE_armature_where_is_bone(struct Bone *bone, struct Bone *prevbone, const bool use_recursion); void BKE_pose_clear_pointers(struct bPose *pose); void BKE_pose_rebuild(struct Object *ob, struct bArmature *arm); +void BKE_pose_rebuild_ex(struct Object *ob, struct bArmature *arm, const bool sort_bones); void BKE_pose_where_is(struct Scene *scene, struct Object *ob); void BKE_pose_where_is_bone(struct Scene *scene, struct Object *ob, struct bPoseChannel *pchan, float ctime, bool do_extra); void BKE_pose_where_is_bone_tail(struct bPoseChannel *pchan); diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index c644fe09364..cc508aa0511 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -1781,6 +1781,7 @@ static void pose_proxy_synchronize(Object *ob, Object *from, int layer_protected BLI_duplicatelist(&pose->agroups, &frompose->agroups); pose->active_group = frompose->active_group; + BKE_pose_channels_hash_make(frompose); for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) { pchanp = BKE_pose_channel_find_name(frompose, pchan->name); @@ -1916,7 +1917,7 @@ void BKE_pose_clear_pointers(bPose *pose) /* only after leave editmode, duplicating, validating older files, library syncing */ /* NOTE: pose->flag is set for it */ -void BKE_pose_rebuild(Object *ob, bArmature *arm) +void BKE_pose_rebuild_ex(Object *ob, bArmature *arm, const bool sort_bones) { Bone *bone; bPose *pose; @@ -1963,8 +1964,9 @@ void BKE_pose_rebuild(Object *ob, bArmature *arm) #ifdef WITH_LEGACY_DEPSGRAPH /* the sorting */ /* Sorting for new dependnecy graph is done on the scene graph level. */ - if (counter > 1) + if (counter > 1 && sort_bones) { DAG_pose_sort(ob); + } #endif ob->pose->flag &= ~POSE_RECALC; @@ -1973,6 +1975,11 @@ void BKE_pose_rebuild(Object *ob, bArmature *arm) BKE_pose_channels_hash_make(ob->pose); } +void BKE_pose_rebuild(Object *ob, bArmature *arm) +{ + BKE_pose_rebuild_ex(ob, arm, true); +} + /* ********************** THE POSE SOLVER ******************* */ /* loc/rot/size to given mat4 */ diff --git a/source/blender/blenkernel/intern/cachefile.c b/source/blender/blenkernel/intern/cachefile.c index 6a08673144e..deeb35bd880 100644 --- a/source/blender/blenkernel/intern/cachefile.c +++ b/source/blender/blenkernel/intern/cachefile.c @@ -93,7 +93,9 @@ void BKE_cachefile_free(CacheFile *cache_file) ABC_free_handle(cache_file->handle); #endif - BLI_mutex_free(cache_file->handle_mutex); + if (cache_file->handle_mutex) { + BLI_mutex_free(cache_file->handle_mutex); + } BLI_freelistN(&cache_file->object_paths); } diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index 9abf09a0944..f747bdb91fa 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -1761,7 +1761,8 @@ void BKE_library_make_local( it->link = NULL; do_loop = true; } - else { /* Only used by linked data, potential candidate to ugly lib-only dependency cycles... */ + /* Only used by linked data, potential candidate to ugly lib-only dependency cycles... */ + else if ((id->tag & LIB_TAG_DOIT) == 0) { /* Check TAG_DOIT to avoid adding same ID several times... */ /* Note that we store the node, not directly ID pointer, that way if it->link is set to NULL * later we can skip it in lib-dependency cycles search later. */ BLI_linklist_prepend_arena(&linked_loop_candidates, it, linklist_mem); @@ -1804,6 +1805,7 @@ void BKE_library_make_local( BKE_libblock_unlink(bmain, id, false, false); BKE_libblock_free(bmain, id); #endif + ((LinkNode *)it->link)->link = NULL; /* Not strictly necessary, but safer (see T49903)... */ it->link = NULL; } } diff --git a/source/blender/blenkernel/intern/mesh_evaluate.c b/source/blender/blenkernel/intern/mesh_evaluate.c index fa113ef5eef..016c9c863f0 100644 --- a/source/blender/blenkernel/intern/mesh_evaluate.c +++ b/source/blender/blenkernel/intern/mesh_evaluate.c @@ -58,6 +58,7 @@ #include "BLI_strict_flags.h" +#include "atomic_ops.h" #include "mikktspace.h" // #define DEBUG_TIME @@ -236,7 +237,9 @@ static void mesh_calc_normals_poly_accum_task_cb(void *userdata, const int pidx) const float fac = saacos(-dot_v3v3(cur_edge, prev_edge)); /* accumulate */ - madd_v3_v3fl(vnors[ml[i].v], pnor, fac); + for (int k = 3; k--; ) { + atomic_add_fl(&vnors[ml[i].v][k], pnor[k] * fac); + } prev_edge = cur_edge; } } diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c index 9eefcbe4885..73678187e80 100644 --- a/source/blender/blenkernel/intern/rigidbody.c +++ b/source/blender/blenkernel/intern/rigidbody.c @@ -799,6 +799,18 @@ static void rigidbody_validate_sim_constraint(RigidBodyWorld *rbw, Object *ob, b RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_Z, rbc->spring_stiffness_z); RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_Z, rbc->spring_damping_z); + RB_constraint_set_spring_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_X, rbc->flag & RBC_FLAG_USE_SPRING_ANG_X); + RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_X, rbc->spring_stiffness_ang_x); + RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_X, rbc->spring_damping_ang_x); + + RB_constraint_set_spring_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_Y, rbc->flag & RBC_FLAG_USE_SPRING_ANG_Y); + RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_Y, rbc->spring_stiffness_ang_y); + RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_Y, rbc->spring_damping_ang_y); + + RB_constraint_set_spring_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_Z, rbc->flag & RBC_FLAG_USE_SPRING_ANG_Z); + RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_Z, rbc->spring_stiffness_ang_z); + RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_Z, rbc->spring_damping_ang_z); + RB_constraint_set_equilibrium_6dof_spring(rbc->physics_constraint); /* fall-through */ case RBC_TYPE_6DOF: @@ -1057,9 +1069,15 @@ RigidBodyCon *BKE_rigidbody_create_constraint(Scene *UNUSED(scene), Object *ob, rbc->spring_damping_x = 0.5f; rbc->spring_damping_y = 0.5f; rbc->spring_damping_z = 0.5f; + rbc->spring_damping_ang_x = 0.5f; + rbc->spring_damping_ang_y = 0.5f; + rbc->spring_damping_ang_z = 0.5f; rbc->spring_stiffness_x = 10.0f; rbc->spring_stiffness_y = 10.0f; rbc->spring_stiffness_z = 10.0f; + rbc->spring_stiffness_ang_x = 10.0f; + rbc->spring_stiffness_ang_y = 10.0f; + rbc->spring_stiffness_ang_z = 10.0f; rbc->motor_lin_max_impulse = 1.0f; rbc->motor_lin_target_velocity = 1.0f; diff --git a/source/blender/blenloader/intern/versioning_270.c b/source/blender/blenloader/intern/versioning_270.c index e9c51d5dc38..529233c0dac 100644 --- a/source/blender/blenloader/intern/versioning_270.c +++ b/source/blender/blenloader/intern/versioning_270.c @@ -52,6 +52,7 @@ #include "DNA_actuator_types.h" #include "DNA_view3d_types.h" #include "DNA_smoke_types.h" +#include "DNA_rigidbody_types.h" #include "DNA_genfile.h" @@ -1359,5 +1360,20 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main) } } } + + if (!DNA_struct_elem_find(fd->filesdna, "RigidBodyCon", "float", "spring_stiffness_ang_x")) { + Object *ob; + for (ob = main->object.first; ob; ob = ob->id.next) { + RigidBodyCon *rbc = ob->rigidbody_constraint; + if (rbc) { + rbc->spring_stiffness_ang_x = 10.0; + rbc->spring_stiffness_ang_y = 10.0; + rbc->spring_stiffness_ang_z = 10.0; + rbc->spring_damping_ang_x = 0.5; + rbc->spring_damping_ang_y = 0.5; + rbc->spring_damping_ang_z = 0.5; + } + } + } } } diff --git a/source/blender/collada/TransformWriter.cpp b/source/blender/collada/TransformWriter.cpp index b16e2e2b0d3..908111ebae6 100644 --- a/source/blender/collada/TransformWriter.cpp +++ b/source/blender/collada/TransformWriter.cpp @@ -113,11 +113,6 @@ void TransformWriter::add_node_transform_ob(COLLADASW::Node& node, Object *ob, B node.addMatrix("transform",d_obmat); break; } - case BC_TRANSFORMATION_TYPE_BOTH: - { - node.addMatrix("transform",d_obmat); - /* fall-through */ - } case BC_TRANSFORMATION_TYPE_TRANSROTLOC: { float loc[3], rot[3], scale[3]; diff --git a/source/blender/collada/collada.h b/source/blender/collada/collada.h index 0017c66836a..a4416608584 100644 --- a/source/blender/collada/collada.h +++ b/source/blender/collada/collada.h @@ -43,8 +43,7 @@ typedef enum BC_export_mesh_type { typedef enum BC_export_transformation_type { BC_TRANSFORMATION_TYPE_MATRIX, - BC_TRANSFORMATION_TYPE_TRANSROTLOC, - BC_TRANSFORMATION_TYPE_BOTH + BC_TRANSFORMATION_TYPE_TRANSROTLOC } BC_export_transformation_type; struct bContext; diff --git a/source/blender/compositor/operations/COM_TextureOperation.cpp b/source/blender/compositor/operations/COM_TextureOperation.cpp index bba5c8702b8..6bfd8ae3888 100644 --- a/source/blender/compositor/operations/COM_TextureOperation.cpp +++ b/source/blender/compositor/operations/COM_TextureOperation.cpp @@ -118,7 +118,7 @@ void TextureBaseOperation::executePixelSampled(float output[4], float x, float y * interpolaiton and (b) in such configuration multitex() sinply floor's the value * which often produces artifacts. */ - if ((m_texture->imaflag & TEX_INTERPOL) == 0) { + if (m_texture != NULL && (m_texture->imaflag & TEX_INTERPOL) == 0) { u += 0.5f / cx; v += 0.5f / cy; } diff --git a/source/blender/depsgraph/CMakeLists.txt b/source/blender/depsgraph/CMakeLists.txt index fd2a521bec5..ab12a8d5b3e 100644 --- a/source/blender/depsgraph/CMakeLists.txt +++ b/source/blender/depsgraph/CMakeLists.txt @@ -45,6 +45,7 @@ set(SRC intern/builder/deg_builder_nodes.cc intern/builder/deg_builder_pchanmap.cc intern/builder/deg_builder_relations.cc + intern/builder/deg_builder_relations_keys.cc intern/builder/deg_builder_transitive.cc intern/debug/deg_debug_graphviz.cc intern/eval/deg_eval.cc diff --git a/source/blender/depsgraph/intern/builder/deg_builder_cycle.cc b/source/blender/depsgraph/intern/builder/deg_builder_cycle.cc index 225cc64ae4d..d84a590b29f 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_cycle.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_cycle.cc @@ -56,12 +56,14 @@ struct StackEntry { void deg_graph_detect_cycles(Depsgraph *graph) { - /* Not is not visited at all during traversal. */ - const int NODE_NOT_VISITED = 0; - /* Node has been visited during traversal and not in current stack. */ - const int NODE_VISITED = 1; - /* Node has been visited during traversal and is in current stack. */ - const int NODE_IN_STACK = 2; + enum { + /* Not is not visited at all during traversal. */ + NODE_NOT_VISITED = 0, + /* Node has been visited during traversal and not in current stack. */ + NODE_VISITED = 1, + /* Node has been visited during traversal and is in current stack. */ + NODE_IN_STACK = 2, + }; std::stack<StackEntry> traversal_stack; foreach (OperationDepsNode *node, graph->operations) { @@ -77,21 +79,23 @@ void deg_graph_detect_cycles(Depsgraph *graph) entry.from = NULL; entry.via_relation = NULL; traversal_stack.push(entry); - node->done = NODE_IN_STACK; + node->tag = NODE_IN_STACK; } else { - node->done = NODE_NOT_VISITED; + node->tag = NODE_NOT_VISITED; } + node->done = 0; } while (!traversal_stack.empty()) { - StackEntry &entry = traversal_stack.top(); + StackEntry entry = traversal_stack.top(); OperationDepsNode *node = entry.node; bool all_child_traversed = true; - foreach (DepsRelation *rel, node->outlinks) { + for (int i = node->done; i < node->outlinks.size(); ++i) { + DepsRelation *rel = node->outlinks[i]; if (rel->to->type == DEPSNODE_TYPE_OPERATION) { OperationDepsNode *to = (OperationDepsNode *)rel->to; - if (to->done == NODE_IN_STACK) { + if (to->tag == NODE_IN_STACK) { printf("Dependency cycle detected:\n"); printf(" '%s' depends on '%s' through '%s'\n", to->full_identifier().c_str(), @@ -107,23 +111,24 @@ void deg_graph_detect_cycles(Depsgraph *graph) current->via_relation->name); current = current->from; } - /* TODO(sergey): So called roussian rlette cycle solver. */ + /* TODO(sergey): So called russian roulette cycle solver. */ rel->flag |= DEPSREL_FLAG_CYCLIC; } - else if (to->done == NODE_NOT_VISITED) { + else if (to->tag == NODE_NOT_VISITED) { StackEntry new_entry; new_entry.node = to; new_entry.from = &entry; new_entry.via_relation = rel; traversal_stack.push(new_entry); - to->done = NODE_IN_STACK; + to->tag = NODE_IN_STACK; all_child_traversed = false; + node->done = i; break; } } } if (all_child_traversed) { - node->done = NODE_VISITED; + node->tag = NODE_VISITED; traversal_stack.pop(); } } diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc index c470e6fb239..5230e7a38b0 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc @@ -34,7 +34,6 @@ #include <stdio.h> #include <stdlib.h> -#include <string.h> #include "MEM_guardedalloc.h" @@ -129,8 +128,7 @@ RootDepsNode *DepsgraphNodeBuilder::add_root_node() IDDepsNode *DepsgraphNodeBuilder::add_id_node(ID *id) { - const char *idtype_name = BKE_idcode_to_name(GS(id->name)); - return m_graph->add_id_node(id, string(id->name + 2) + "[" + idtype_name + "]"); + return m_graph->add_id_node(id, id->name); } TimeSourceDepsNode *DepsgraphNodeBuilder::add_time_source(ID *id) @@ -177,7 +175,7 @@ TimeSourceDepsNode *DepsgraphNodeBuilder::add_time_source(ID *id) ComponentDepsNode *DepsgraphNodeBuilder::add_component_node( ID *id, eDepsNode_Type comp_type, - const string &comp_name) + const char *comp_name) { IDDepsNode *id_node = add_id_node(id); ComponentDepsNode *comp_node = id_node->add_component(comp_type, comp_name); @@ -190,15 +188,19 @@ OperationDepsNode *DepsgraphNodeBuilder::add_operation_node( eDepsOperation_Type optype, DepsEvalOperationCb op, eDepsOperation_Code opcode, - const string &description) + const char *name, + int name_tag) { - OperationDepsNode *op_node = comp_node->has_operation(opcode, description); + OperationDepsNode *op_node = comp_node->has_operation(opcode, + name, + name_tag); if (op_node == NULL) { - op_node = comp_node->add_operation(optype, op, opcode, description); + op_node = comp_node->add_operation(optype, op, opcode, name, name_tag); m_graph->operations.push_back(op_node); } else { - fprintf(stderr, "add_operation: Operation already exists - %s has %s at %p\n", + fprintf(stderr, + "add_operation: Operation already exists - %s has %s at %p\n", comp_node->identifier().c_str(), op_node->identifier().c_str(), op_node); @@ -210,14 +212,15 @@ OperationDepsNode *DepsgraphNodeBuilder::add_operation_node( OperationDepsNode *DepsgraphNodeBuilder::add_operation_node( ID *id, eDepsNode_Type comp_type, - const string &comp_name, + const char *comp_name, eDepsOperation_Type optype, DepsEvalOperationCb op, eDepsOperation_Code opcode, - const string &description) + const char *name, + int name_tag) { ComponentDepsNode *comp_node = add_component_node(id, comp_type, comp_name); - return add_operation_node(comp_node, optype, op, opcode, description); + return add_operation_node(comp_node, optype, op, opcode, name, name_tag); } OperationDepsNode *DepsgraphNodeBuilder::add_operation_node( @@ -226,38 +229,54 @@ OperationDepsNode *DepsgraphNodeBuilder::add_operation_node( eDepsOperation_Type optype, DepsEvalOperationCb op, eDepsOperation_Code opcode, - const string& description) + const char *name, + int name_tag) { - return add_operation_node(id, comp_type, "", optype, op, opcode, description); + return add_operation_node(id, + comp_type, + "", + optype, + op, + opcode, + name, + name_tag); } bool DepsgraphNodeBuilder::has_operation_node(ID *id, eDepsNode_Type comp_type, - const string &comp_name, + const char *comp_name, eDepsOperation_Code opcode, - const string &description) + const char *name, + int name_tag) { - return find_operation_node(id, comp_type, comp_name, opcode, description) != NULL; + return find_operation_node(id, + comp_type, + comp_name, + opcode, + name, + name_tag) != NULL; } OperationDepsNode *DepsgraphNodeBuilder::find_operation_node( ID *id, eDepsNode_Type comp_type, - const string &comp_name, + const char *comp_name, eDepsOperation_Code opcode, - const string &description) + const char *name, + int name_tag) { ComponentDepsNode *comp_node = add_component_node(id, comp_type, comp_name); - return comp_node->has_operation(opcode, description); + return comp_node->has_operation(opcode, name, name_tag); } OperationDepsNode *DepsgraphNodeBuilder::find_operation_node( ID *id, eDepsNode_Type comp_type, eDepsOperation_Code opcode, - const string& description) + const char *name, + int name_tag) { - return find_operation_node(id, comp_type, "", opcode, description); + return find_operation_node(id, comp_type, "", opcode, name, name_tag); } /* **** Build functions for entity nodes **** */ @@ -610,12 +629,17 @@ OperationDepsNode *DepsgraphNodeBuilder::build_driver(ID *id, FCurve *fcu) OperationDepsNode *driver_op = find_operation_node(id, DEPSNODE_TYPE_PARAMETERS, DEG_OPCODE_DRIVER, - deg_fcurve_id_name(fcu)); + fcu->rna_path, + fcu->array_index); if (driver_op == NULL) { - driver_op = add_operation_node(id, DEPSNODE_TYPE_PARAMETERS, - DEPSOP_TYPE_EXEC, function_bind(BKE_animsys_eval_driver, _1, id, fcu), - DEG_OPCODE_DRIVER, deg_fcurve_id_name(fcu)); + driver_op = add_operation_node(id, + DEPSNODE_TYPE_PARAMETERS, + DEPSOP_TYPE_EXEC, + function_bind(BKE_animsys_eval_driver, _1, id, fcu), + DEG_OPCODE_DRIVER, + fcu->rna_path, + fcu->array_index); } /* tag "scripted expression" drivers as needing Python (due to GIL issues, etc.) */ @@ -760,7 +784,7 @@ void DepsgraphNodeBuilder::build_rig(Scene *scene, Object *ob) /* Rebuild pose if not up to date. */ if (ob->pose == NULL || (ob->pose->flag & POSE_RECALC)) { - BKE_pose_rebuild(ob, arm); + BKE_pose_rebuild_ex(ob, arm, false); /* XXX: Without this animation gets lost in certain circumstances * after loading file. Need to investigate further since it does * not happen with simple scenes.. @@ -1124,15 +1148,20 @@ void DepsgraphNodeBuilder::build_nodetree(DepsNode *owner_node, bNodeTree *ntree /* nodetree's nodes... */ for (bNode *bnode = (bNode *)ntree->nodes.first; bnode; bnode = bnode->next) { - if (bnode->id) { - if (GS(bnode->id->name) == ID_MA) { - build_material(owner_node, (Material *)bnode->id); + ID *id = bnode->id; + if (id != NULL) { + short id_type = GS(id->name); + if (id_type == ID_MA) { + build_material(owner_node, (Material *)id); } - else if (bnode->type == ID_TE) { - build_texture(owner_node, (Tex *)bnode->id); + else if (id_type == ID_TE) { + build_texture(owner_node, (Tex *)id); + } + else if (id_type == ID_IM) { + build_image((Image *)id); } else if (bnode->type == NODE_GROUP) { - bNodeTree *group_ntree = (bNodeTree *)bnode->id; + bNodeTree *group_ntree = (bNodeTree *)id; if ((group_ntree->id.tag & LIB_TAG_DOIT) == 0) { build_nodetree(owner_node, group_ntree); } @@ -1189,10 +1218,33 @@ void DepsgraphNodeBuilder::build_texture(DepsNode *owner_node, Tex *tex) return; } tex_id->tag |= LIB_TAG_DOIT; - /* texture itself */ + /* Texture itself. */ build_animdata(tex_id); - /* texture's nodetree */ + /* Texture's nodetree. */ build_nodetree(owner_node, tex->nodetree); + /* Special cases for different IDs which texture uses. */ + if (tex->type == TEX_IMAGE) { + if (tex->ima != NULL) { + build_image(tex->ima); + } + } +} + +void DepsgraphNodeBuilder::build_image(Image *image) { + ID *image_id = &image->id; + if (image_id->tag & LIB_TAG_DOIT) { + return; + } + image_id->tag |= LIB_TAG_DOIT; + /* Image ID node itself. */ + add_id_node(image_id); + /* Placeholder so we can add relations and tag ID node for update. */ + add_operation_node(image_id, + DEPSNODE_TYPE_PARAMETERS, + DEPSOP_TYPE_EXEC, + NULL, + DEG_OPCODE_PLACEHOLDER, + "Image Eval"); } void DepsgraphNodeBuilder::build_compositor(Scene *scene) diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h index f378f076804..72dc73357bf 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h @@ -38,6 +38,7 @@ struct bGPdata; struct ListBase; struct GHash; struct ID; +struct Image; struct FCurve; struct Group; struct Key; @@ -75,43 +76,49 @@ struct DepsgraphNodeBuilder { ComponentDepsNode *add_component_node(ID *id, eDepsNode_Type comp_type, - const string& comp_name = ""); + const char *comp_name = ""); OperationDepsNode *add_operation_node(ComponentDepsNode *comp_node, eDepsOperation_Type optype, DepsEvalOperationCb op, eDepsOperation_Code opcode, - const string& description = ""); + const char *name = "", + int name_tag = -1); OperationDepsNode *add_operation_node(ID *id, eDepsNode_Type comp_type, - const string& comp_name, + const char *comp_name, eDepsOperation_Type optype, DepsEvalOperationCb op, eDepsOperation_Code opcode, - const string& description = ""); + const char *name = "", + int name_tag = -1); OperationDepsNode *add_operation_node(ID *id, eDepsNode_Type comp_type, eDepsOperation_Type optype, DepsEvalOperationCb op, eDepsOperation_Code opcode, - const string& description = ""); + const char *name = "", + int name_tag = -1); bool has_operation_node(ID *id, eDepsNode_Type comp_type, - const string& comp_name, + const char *comp_name, eDepsOperation_Code opcode, - const string& description = ""); + const char *name = "", + int name_tag = -1); OperationDepsNode *find_operation_node(ID *id, eDepsNode_Type comp_type, - const string &comp_name, + const char *comp_name, eDepsOperation_Code opcode, - const string &description = ""); + const char *name = "", + int name_tag = -1); OperationDepsNode *find_operation_node(ID *id, eDepsNode_Type comp_type, eDepsOperation_Code opcode, - const string &description = ""); + const char *name = "", + int name_tag = -1); void build_scene(Main *bmain, Scene *scene); SubgraphDepsNode *build_subgraph(Group *group); @@ -142,6 +149,7 @@ struct DepsgraphNodeBuilder { void build_material(DepsNode *owner_node, Material *ma); void build_texture(DepsNode *owner_node, Tex *tex); void build_texture_stack(DepsNode *owner_node, MTex **texture_stack); + void build_image(Image *image); void build_world(World *world); void build_compositor(Scene *scene); void build_gpencil(bGPdata *gpd); diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 232c801563e..ccc4ea3d47b 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -34,13 +34,12 @@ #include <stdio.h> #include <stdlib.h> -#include <string.h> +#include <cstring> /* required for STREQ later on. */ #include "MEM_guardedalloc.h" extern "C" { #include "BLI_blenlib.h" -#include "BLI_string.h" #include "BLI_utildefines.h" #include "DNA_action_types.h" @@ -209,10 +208,12 @@ OperationDepsNode *DepsgraphRelationBuilder::find_node( return NULL; } - OperationDepsNode *op_node = comp_node->find_operation(key.opcode, key.name); + OperationDepsNode *op_node = comp_node->find_operation(key.opcode, + key.name, + key.name_tag); if (!op_node) { fprintf(stderr, "find_node_operation: Failed for (%s, '%s')\n", - DEG_OPNAMES[key.opcode], key.name.c_str()); + DEG_OPNAMES[key.opcode], key.name); } return op_node; } @@ -234,7 +235,7 @@ OperationDepsNode *DepsgraphRelationBuilder::has_node( if (!comp_node) { return NULL; } - return comp_node->has_operation(key.opcode, key.name); + return comp_node->has_operation(key.opcode, key.name, key.name_tag); } void DepsgraphRelationBuilder::add_time_relation(TimeSourceDepsNode *timesrc, @@ -483,7 +484,7 @@ void DepsgraphRelationBuilder::build_object(Main *bmain, Scene *scene, Object *o build_animdata(&ob->id); // XXX: This should be hooked up by the build_animdata code - if (ob->adt && (ob->adt->action || ob->adt->nla_tracks.first)) { + if (needs_animdata_node(&ob->id)) { ComponentKey adt_key(&ob->id, DEPSNODE_TYPE_ANIMATION); add_relation(adt_key, local_transform_key, DEPSREL_TYPE_OPERATION, "Object Animation"); } @@ -815,11 +816,66 @@ void DepsgraphRelationBuilder::build_animdata(ID *id) /* drivers */ for (FCurve *fcu = (FCurve *)adt->drivers.first; fcu; fcu = fcu->next) { - OperationKey driver_key(id, DEPSNODE_TYPE_PARAMETERS, DEG_OPCODE_DRIVER, deg_fcurve_id_name(fcu)); + OperationKey driver_key(id, + DEPSNODE_TYPE_PARAMETERS, + DEG_OPCODE_DRIVER, + fcu->rna_path, + fcu->array_index); /* create the driver's relations to targets */ build_driver(id, fcu); + /* Special case for array drivers: we can not multithread them because + * of the way how they work internally: animation system will write the + * whole array back to RNA even when changing individual array value. + * + * Some tricky things here: + * - array_index is -1 for single channel drivers, meaning we only have + * to do some magic when array_index is not -1. + * - We do relation from next array index to a previous one, so we don't + * have to deal with array index 0. + * + * TODO(sergey): Avoid liner lookup somehow. + */ + if (fcu->array_index > 0) { + FCurve *fcu_prev = NULL; + for (FCurve *fcu_candidate = (FCurve *)adt->drivers.first; + fcu_candidate != NULL; + fcu_candidate = fcu_candidate->next) + { + /* Writing to different RNA paths is */ + if (!STREQ(fcu_candidate->rna_path, fcu->rna_path)) { + continue; + } + /* We only do relation from previous fcurve to previous one. */ + if (fcu_candidate->array_index >= fcu->array_index) { + continue; + } + /* Choose fcurve with highest possible array index. */ + if (fcu_prev == NULL || + fcu_candidate->array_index > fcu_prev->array_index) + { + fcu_prev = fcu_candidate; + } + } + if (fcu_prev != NULL) { + OperationKey prev_driver_key(id, + DEPSNODE_TYPE_PARAMETERS, + DEG_OPCODE_DRIVER, + fcu_prev->rna_path, + fcu_prev->array_index); + OperationKey driver_key(id, + DEPSNODE_TYPE_PARAMETERS, + DEG_OPCODE_DRIVER, + fcu->rna_path, + fcu->array_index); + add_relation(prev_driver_key, + driver_key, + DEPSREL_TYPE_OPERATION, + "[Driver Order]"); + } + } + /* prevent driver from occurring before own animation... */ if (adt->action || adt->nla_tracks.first) { add_relation(adt_key, driver_key, DEPSREL_TYPE_OPERATION, @@ -831,7 +887,11 @@ void DepsgraphRelationBuilder::build_animdata(ID *id) void DepsgraphRelationBuilder::build_driver(ID *id, FCurve *fcu) { ChannelDriver *driver = fcu->driver; - OperationKey driver_key(id, DEPSNODE_TYPE_PARAMETERS, DEG_OPCODE_DRIVER, deg_fcurve_id_name(fcu)); + OperationKey driver_key(id, + DEPSNODE_TYPE_PARAMETERS, + DEG_OPCODE_DRIVER, + fcu->rna_path, + fcu->array_index); bPoseChannel *pchan = NULL; /* create dependency between driver and data affected by it */ @@ -1384,7 +1444,7 @@ void DepsgraphRelationBuilder::build_rig(Scene *scene, Object *ob) "Armature Eval"); add_relation(armature_key, init_key, DEPSREL_TYPE_COMPONENT_ORDER, "Data dependency"); - if (ob->adt && (ob->adt->action || ob->adt->nla_tracks.first)) { + if (needs_animdata_node(&ob->id)) { ComponentKey animation_key(&ob->id, DEPSNODE_TYPE_ANIMATION); add_relation(animation_key, init_key, DEPSREL_TYPE_OPERATION, "Rig Animation"); } @@ -1622,7 +1682,7 @@ void DepsgraphRelationBuilder::build_obdata_geom(Main *bmain, Scene *scene, Obje * for either the modifier needing time, or that it is animated. */ /* XXX: Remove this hack when these links are added as part of build_animdata() instead */ - if (modifier_dependsOnTime(md) == false) { + if (modifier_dependsOnTime(md) == false && needs_animdata_node(&ob->id)) { ComponentKey animation_key(&ob->id, DEPSNODE_TYPE_ANIMATION); add_relation(animation_key, mod_key, DEPSREL_TYPE_OPERATION, "Modifier Animation"); } @@ -1920,7 +1980,7 @@ bool DepsgraphRelationBuilder::needs_animdata_node(ID *id) { AnimData *adt = BKE_animdata_from_id(id); if (adt != NULL) { - return adt->action != NULL; + return (adt->action != NULL) || (adt->nla_tracks.first != NULL); } return false; } diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.h b/source/blender/depsgraph/intern/builder/deg_builder_relations.h index ac6e6f8f095..28dd63a7c17 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.h @@ -81,108 +81,83 @@ struct ComponentDepsNode; struct OperationDepsNode; struct RootPChanMap; -struct RootKey -{ - RootKey() {} +struct RootKey { + RootKey(); }; struct TimeSourceKey { - TimeSourceKey() : id(NULL) {} - TimeSourceKey(ID *id) : id(id) {} + TimeSourceKey(); + TimeSourceKey(ID *id); - string identifier() const - { - return string("TimeSourceKey"); - } + string identifier() const; ID *id; }; struct ComponentKey { - ComponentKey() : - id(NULL), type(DEPSNODE_TYPE_UNDEFINED), name("") - {} - ComponentKey(ID *id, eDepsNode_Type type, const string &name = "") : - id(id), type(type), name(name) - {} - - string identifier() const - { - const char *idname = (id) ? id->name : "<None>"; + ComponentKey(); + ComponentKey(ID *id, eDepsNode_Type type, const char *name = ""); - char typebuf[5]; - BLI_snprintf(typebuf, sizeof(typebuf), "%d", type); - - return string("ComponentKey(") + idname + ", " + typebuf + ", '" + name + "')"; - } + string identifier() const; ID *id; eDepsNode_Type type; - string name; + const char *name; }; struct OperationKey { - OperationKey() : - id(NULL), component_type(DEPSNODE_TYPE_UNDEFINED), component_name(""), opcode(DEG_OPCODE_OPERATION), name("") - {} - - OperationKey(ID *id, eDepsNode_Type component_type, const string &name) : - id(id), component_type(component_type), component_name(""), opcode(DEG_OPCODE_OPERATION), name(name) - {} - OperationKey(ID *id, eDepsNode_Type component_type, const string &component_name, const string &name) : - id(id), component_type(component_type), component_name(component_name), opcode(DEG_OPCODE_OPERATION), name(name) - {} - - OperationKey(ID *id, eDepsNode_Type component_type, eDepsOperation_Code opcode) : - id(id), component_type(component_type), component_name(""), opcode(opcode), name("") - {} - OperationKey(ID *id, eDepsNode_Type component_type, const string &component_name, eDepsOperation_Code opcode) : - id(id), component_type(component_type), component_name(component_name), opcode(opcode), name("") - {} - - OperationKey(ID *id, eDepsNode_Type component_type, eDepsOperation_Code opcode, const string &name) : - id(id), component_type(component_type), component_name(""), opcode(opcode), name(name) - {} - OperationKey(ID *id, eDepsNode_Type component_type, const string &component_name, eDepsOperation_Code opcode, const string &name) : - id(id), component_type(component_type), component_name(component_name), opcode(opcode), name(name) - {} - - string identifier() const - { - char typebuf[5]; - BLI_snprintf(typebuf, sizeof(typebuf), "%d", component_type); - - return string("OperationKey(") + "t: " + typebuf + ", cn: '" + component_name + "', c: " + DEG_OPNAMES[opcode] + ", n: '" + name + "')"; - } - + OperationKey(); + OperationKey(ID *id, + eDepsNode_Type component_type, + const char *name, + int name_tag = -1); + OperationKey(ID *id, + eDepsNode_Type component_type, + const char *component_name, + const char *name, + int name_tag); + + OperationKey(ID *id, + eDepsNode_Type component_type, + eDepsOperation_Code opcode); + OperationKey(ID *id, + eDepsNode_Type component_type, + const char *component_name, + eDepsOperation_Code opcode); + + OperationKey(ID *id, + eDepsNode_Type component_type, + eDepsOperation_Code opcode, + const char *name, + int name_tag = -1); + OperationKey(ID *id, + eDepsNode_Type component_type, + const char *component_name, + eDepsOperation_Code opcode, + const char *name, + int name_tag = -1); + + string identifier() const; ID *id; eDepsNode_Type component_type; - string component_name; + const char *component_name; eDepsOperation_Code opcode; - string name; + const char *name; + int name_tag; }; struct RNAPathKey { - // Note: see depsgraph_build.cpp for implementation + /* NOTE: see depsgraph_build.cpp for implementation */ RNAPathKey(ID *id, const char *path); - RNAPathKey(ID *id, const PointerRNA &ptr, PropertyRNA *prop) : - id(id), ptr(ptr), prop(prop) - {} - - string identifier() const - { - const char *id_name = (id) ? id->name : "<No ID>"; - const char *prop_name = (prop) ? RNA_property_identifier(prop) : "<No Prop>"; - - return string("RnaPathKey(") + "id: " + id_name + ", prop: " + prop_name + "')"; - } + RNAPathKey(ID *id, const PointerRNA &ptr, PropertyRNA *prop); + string identifier() const; ID *id; PointerRNA ptr; @@ -270,7 +245,7 @@ protected: template <typename KeyType> DepsNodeHandle create_node_handle(const KeyType& key, - const string& default_name = ""); + const char *default_name = ""); bool needs_animdata_node(ID *id); @@ -280,7 +255,7 @@ private: struct DepsNodeHandle { - DepsNodeHandle(DepsgraphRelationBuilder *builder, OperationDepsNode *node, const string &default_name = "") : + DepsNodeHandle(DepsgraphRelationBuilder *builder, OperationDepsNode *node, const char *default_name = "") : builder(builder), node(node), default_name(default_name) @@ -290,7 +265,7 @@ struct DepsNodeHandle DepsgraphRelationBuilder *builder; OperationDepsNode *node; - const string &default_name; + const char *default_name; }; /* Utilities for Builders ----------------------------------------------------- */ @@ -318,6 +293,7 @@ void DepsgraphRelationBuilder::add_relation(const KeyFrom &key_from, else { if (!op_from) { /* XXX TODO handle as error or report if needed */ + node_from = find_node(key_from); fprintf(stderr, "add_relation(%d, %s) - Could not find op_from (%s)\n", type, description, key_from.identifier().c_str()); } @@ -383,7 +359,7 @@ void DepsgraphRelationBuilder::add_node_handle_relation( template <typename KeyType> DepsNodeHandle DepsgraphRelationBuilder::create_node_handle( const KeyType &key, - const string &default_name) + const char *default_name) { return DepsNodeHandle(this, find_node(key), default_name); } diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_keys.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_keys.cc new file mode 100644 index 00000000000..7ada04e8f74 --- /dev/null +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_keys.cc @@ -0,0 +1,211 @@ +/* + * ***** 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) 2013 Blender Foundation. + * All rights reserved. + * + * Original Author: Joshua Leung + * Contributor(s): Based on original depsgraph.c code - Blender Foundation (2005-2013) + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/depsgraph/intern/builder/deg_builder_relations.cc + * \ingroup depsgraph + * + * Methods for constructing depsgraph + */ + +#include "intern/builder/deg_builder_relations.h" + +namespace DEG { + +///////////////////////////////////////// +// Root. + +RootKey::RootKey() +{ +} + +///////////////////////////////////////// +// Time source. + +TimeSourceKey::TimeSourceKey() + : id(NULL) +{ +} + +TimeSourceKey::TimeSourceKey(ID *id) + : id(id) +{ +} + +string TimeSourceKey::identifier() const +{ + return string("TimeSourceKey"); +} + +///////////////////////////////////////// +// Component. + +ComponentKey::ComponentKey() + : id(NULL), + type(DEPSNODE_TYPE_UNDEFINED), + name("") +{ +} + +ComponentKey::ComponentKey(ID *id, eDepsNode_Type type, const char *name) + : id(id), + type(type), + name(name) +{ +} + +string ComponentKey::identifier() const +{ + const char *idname = (id) ? id->name : "<None>"; + char typebuf[5]; + BLI_snprintf(typebuf, sizeof(typebuf), "%d", type); + return string("ComponentKey(") + + idname + ", " + typebuf + ", '" + name + "')"; +} + +///////////////////////////////////////// +// Operation. + +OperationKey::OperationKey() + : id(NULL), + component_type(DEPSNODE_TYPE_UNDEFINED), + component_name(""), + opcode(DEG_OPCODE_OPERATION), + name(""), + name_tag(-1) +{ +} + +OperationKey::OperationKey(ID *id, + eDepsNode_Type component_type, + const char *name, + int name_tag) + : id(id), + component_type(component_type), + component_name(""), + opcode(DEG_OPCODE_OPERATION), + name(name), + name_tag(name_tag) +{ +} + +OperationKey::OperationKey(ID *id, + eDepsNode_Type component_type, + const char *component_name, + const char *name, + int name_tag) + : id(id), + component_type(component_type), + component_name(component_name), + opcode(DEG_OPCODE_OPERATION), + name(name), + name_tag(name_tag) +{ +} + +OperationKey::OperationKey(ID *id, + eDepsNode_Type component_type, + eDepsOperation_Code opcode) + : id(id), + component_type(component_type), + component_name(""), + opcode(opcode), + name(""), + name_tag(-1) +{ +} + +OperationKey::OperationKey(ID *id, + eDepsNode_Type component_type, + const char *component_name, + eDepsOperation_Code opcode) + : id(id), + component_type(component_type), + component_name(component_name), + opcode(opcode), + name(""), + name_tag(-1) +{ +} + +OperationKey::OperationKey(ID *id, + eDepsNode_Type component_type, + eDepsOperation_Code opcode, + const char *name, + int name_tag) + : id(id), + component_type(component_type), + component_name(""), + opcode(opcode), + name(name), + name_tag(name_tag) +{ +} + +OperationKey::OperationKey(ID *id, + eDepsNode_Type component_type, + const char *component_name, + eDepsOperation_Code opcode, + const char *name, + int name_tag) + : id(id), + component_type(component_type), + component_name(component_name), + opcode(opcode), + name(name), + name_tag(name_tag) +{ +} + +string OperationKey::identifier() const +{ + char typebuf[5]; + BLI_snprintf(typebuf, sizeof(typebuf), "%d", component_type); + return string("OperationKey(") + + "t: " + typebuf + + ", cn: '" + component_name + + "', c: " + DEG_OPNAMES[opcode] + + ", n: '" + name + "')"; +} + +///////////////////////////////////////// +// RNA path. + +RNAPathKey::RNAPathKey(ID *id, const PointerRNA &ptr, PropertyRNA *prop) + : id(id), + ptr(ptr), + prop(prop) +{ +} + +string RNAPathKey::identifier() const +{ + const char *id_name = (id) ? id->name : "<No ID>"; + const char *prop_name = (prop) ? RNA_property_identifier(prop) : "<No Prop>"; + return string("RnaPathKey(") + "id: " + id_name + + ", prop: " + prop_name + "')"; +} + +} // namespace DEG diff --git a/source/blender/depsgraph/intern/debug/deg_debug_graphviz.cc b/source/blender/depsgraph/intern/debug/deg_debug_graphviz.cc index 70cd5f11a47..0d56ce71c7d 100644 --- a/source/blender/depsgraph/intern/debug/deg_debug_graphviz.cc +++ b/source/blender/depsgraph/intern/debug/deg_debug_graphviz.cc @@ -321,7 +321,7 @@ static void deg_debug_graphviz_node_single(const DebugContext &ctx, static void deg_debug_graphviz_node_cluster_begin(const DebugContext &ctx, const DepsNode *node) { - string name = node->identifier().c_str(); + string name = node->identifier(); if (node->type == DEPSNODE_TYPE_ID_REF) { IDDepsNode *id_node = (IDDepsNode *)node; char buf[256]; diff --git a/source/blender/depsgraph/intern/depsgraph.cc b/source/blender/depsgraph/intern/depsgraph.cc index 2b7c63767ab..3502267d9ca 100644 --- a/source/blender/depsgraph/intern/depsgraph.cc +++ b/source/blender/depsgraph/intern/depsgraph.cc @@ -32,8 +32,6 @@ #include "intern/depsgraph.h" /* own include */ -#include <string.h> - #include "MEM_guardedalloc.h" #include "BLI_utildefines.h" @@ -53,6 +51,8 @@ extern "C" { #include "RNA_access.h" } +#include <cstring> + #include "DEG_depsgraph.h" #include "intern/nodes/deg_node.h" @@ -116,7 +116,7 @@ static bool pointer_to_component_node_criteria(const PointerRNA *ptr, const PropertyRNA *prop, ID **id, eDepsNode_Type *type, - string *subdata) + const char **subdata) { if (!ptr->type) return false; @@ -232,7 +232,7 @@ DepsNode *Depsgraph::find_node_from_pointer(const PointerRNA *ptr, { ID *id; eDepsNode_Type type; - string name; + const char *name; /* Get querying conditions. */ if (pointer_to_id_node_criteria(ptr, prop, &id)) { @@ -240,8 +240,9 @@ DepsNode *Depsgraph::find_node_from_pointer(const PointerRNA *ptr, } else if (pointer_to_component_node_criteria(ptr, prop, &id, &type, &name)) { IDDepsNode *id_node = find_id_node(id); - if (id_node) + if (id_node != NULL) { return id_node->find_component(type, name); + } } return NULL; @@ -328,7 +329,7 @@ IDDepsNode *Depsgraph::find_id_node(const ID *id) const return reinterpret_cast<IDDepsNode *>(BLI_ghash_lookup(id_hash, id)); } -IDDepsNode *Depsgraph::add_id_node(ID *id, const string &name) +IDDepsNode *Depsgraph::add_id_node(ID *id, const char *name) { IDDepsNode *id_node = find_id_node(id); if (!id_node) { diff --git a/source/blender/depsgraph/intern/depsgraph.h b/source/blender/depsgraph/intern/depsgraph.h index 08b264f8497..e668facd645 100644 --- a/source/blender/depsgraph/intern/depsgraph.h +++ b/source/blender/depsgraph/intern/depsgraph.h @@ -101,22 +101,6 @@ struct Depsgraph { ~Depsgraph(); /** - * Find node which matches the specified description. - * - * \param id: ID block that is associated with this - * \param subdata: identifier used for sub-ID data (e.g. bone) - * \param type: type of node we're dealing with - * \param name: custom identifier assigned to node - * - * \return A node matching the required characteristics if it exists - * or NULL if no such node exists in the graph. - */ - DepsNode *find_node(const ID *id, - eDepsNode_Type type, - const string &subdata, - const string &name); - - /** * Convenience wrapper to find node given just pointer + property. * * \param ptr: pointer to the data that node will represent @@ -136,7 +120,7 @@ struct Depsgraph { void clear_subgraph_nodes(); IDDepsNode *find_id_node(const ID *id) const; - IDDepsNode *add_id_node(ID *id, const string &name = ""); + IDDepsNode *add_id_node(ID *id, const char *name = ""); void remove_id_node(const ID *id); void clear_id_nodes(); diff --git a/source/blender/depsgraph/intern/depsgraph_build.cc b/source/blender/depsgraph/intern/depsgraph_build.cc index 119b2054d24..e139ff1f2bc 100644 --- a/source/blender/depsgraph/intern/depsgraph_build.cc +++ b/source/blender/depsgraph/intern/depsgraph_build.cc @@ -32,6 +32,8 @@ #include "MEM_guardedalloc.h" +// #define DEBUG_TIME + extern "C" { #include "DNA_cachefile_types.h" #include "DNA_object_types.h" @@ -41,6 +43,11 @@ extern "C" { #include "BLI_utildefines.h" #include "BLI_ghash.h" +#ifdef DEBUG_TIME +# include "PIL_time.h" +# include "PIL_time_utildefines.h" +#endif + #include "BKE_main.h" #include "BKE_collision.h" #include "BKE_effect.h" @@ -190,6 +197,10 @@ void DEG_add_special_eval_flag(Depsgraph *graph, ID *id, short flag) */ void DEG_graph_build_from_scene(Depsgraph *graph, Main *bmain, Scene *scene) { +#ifdef DEBUG_TIME + TIMEIT_START(DEG_graph_build_from_scene); +#endif + DEG::Depsgraph *deg_graph = reinterpret_cast<DEG::Depsgraph *>(graph); /* 1) Generate all the nodes in the graph first */ @@ -239,6 +250,10 @@ void DEG_graph_build_from_scene(Depsgraph *graph, Main *bmain, Scene *scene) abort(); } #endif + +#ifdef DEBUG_TIME + TIMEIT_END(DEG_graph_build_from_scene); +#endif } /* Tag graph relations for update. */ diff --git a/source/blender/depsgraph/intern/depsgraph_intern.h b/source/blender/depsgraph/intern/depsgraph_intern.h index e5d3d1f5861..2d8e7dc841c 100644 --- a/source/blender/depsgraph/intern/depsgraph_intern.h +++ b/source/blender/depsgraph/intern/depsgraph_intern.h @@ -63,8 +63,8 @@ struct DepsNodeFactory { virtual const char *tname() const = 0; virtual DepsNode *create_node(const ID *id, - const string &subdata, - const string &name) const = 0; + const char *subdata, + const char *name) const = 0; }; template <class NodeType> @@ -73,7 +73,7 @@ struct DepsNodeFactoryImpl : public DepsNodeFactory { eDepsNode_Class tclass() const { return NodeType::typeinfo.tclass; } const char *tname() const { return NodeType::typeinfo.tname; } - DepsNode *create_node(const ID *id, const string &subdata, const string &name) const + DepsNode *create_node(const ID *id, const char *subdata, const char *name) const { DepsNode *node = OBJECT_GUARDED_NEW(NodeType); @@ -81,12 +81,14 @@ struct DepsNodeFactoryImpl : public DepsNodeFactory { node->type = type(); node->tclass = tclass(); - if (!name.empty()) + if (name[0] != '\0') { /* set name if provided ... */ node->name = name; - else + } + else { /* ... otherwise use default type name */ node->name = tname(); + } node->init(id, subdata); diff --git a/source/blender/depsgraph/intern/depsgraph_tag.cc b/source/blender/depsgraph/intern/depsgraph_tag.cc index b61b31a6be6..91eabbaf5d1 100644 --- a/source/blender/depsgraph/intern/depsgraph_tag.cc +++ b/source/blender/depsgraph/intern/depsgraph_tag.cc @@ -31,7 +31,7 @@ */ #include <stdio.h> -#include <cstring> +#include <cstring> /* required for memset */ #include <queue> extern "C" { diff --git a/source/blender/depsgraph/intern/eval/deg_eval_debug.cc b/source/blender/depsgraph/intern/eval/deg_eval_debug.cc index 67d64aae8bf..060544a4407 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval_debug.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval_debug.cc @@ -30,10 +30,10 @@ * Implementation of tools for debugging the depsgraph */ -#include <cstring> - #include "intern/eval/deg_eval_debug.h" +#include <cstring> /* required for STREQ later on. */ + extern "C" { #include "BLI_listbase.h" #include "BLI_ghash.h" @@ -53,10 +53,10 @@ namespace DEG { DepsgraphStats *DepsgraphDebug::stats = NULL; -static string get_component_name(eDepsNode_Type type, const string &name = "") +static string get_component_name(eDepsNode_Type type, const char *name = "") { DepsNodeFactory *factory = deg_get_node_factory(type); - if (name.empty()) { + if (name[0] != '\0') { return string(factory->tname()); } else { @@ -116,7 +116,7 @@ void DepsgraphDebug::task_started(Depsgraph *graph, */ DepsgraphStatsComponent *comp_stats = get_component_stats(id, get_component_name(comp->type, - comp->name), + comp->name).c_str(), true); times_clear(comp_stats->times); } @@ -146,7 +146,7 @@ void DepsgraphDebug::task_completed(Depsgraph *graph, DepsgraphStatsComponent *comp_stats = get_component_stats(id, get_component_name(comp->type, - comp->name), + comp->name).c_str(), true); times_add(comp_stats->times, time); } @@ -226,7 +226,7 @@ DepsgraphStatsID *DepsgraphDebug::get_id_stats(ID *id, bool create) DepsgraphStatsComponent *DepsgraphDebug::get_component_stats( DepsgraphStatsID *id_stats, - const string &name, + const char *name, bool create) { DepsgraphStatsComponent *comp_stats; @@ -234,13 +234,14 @@ DepsgraphStatsComponent *DepsgraphDebug::get_component_stats( comp_stats != NULL; comp_stats = comp_stats->next) { - if (STREQ(comp_stats->name, name.c_str())) + if (STREQ(comp_stats->name, name)) { break; + } } if (!comp_stats && create) { comp_stats = (DepsgraphStatsComponent *)MEM_callocN(sizeof(DepsgraphStatsComponent), "Depsgraph Component Stats"); - BLI_strncpy(comp_stats->name, name.c_str(), sizeof(comp_stats->name)); + BLI_strncpy(comp_stats->name, name, sizeof(comp_stats->name)); BLI_addtail(&id_stats->components, comp_stats); } return comp_stats; diff --git a/source/blender/depsgraph/intern/eval/deg_eval_debug.h b/source/blender/depsgraph/intern/eval/deg_eval_debug.h index 9109019eb2d..0bbe88cc9ca 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval_debug.h +++ b/source/blender/depsgraph/intern/eval/deg_eval_debug.h @@ -66,10 +66,10 @@ struct DepsgraphDebug { static DepsgraphStatsID *get_id_stats(ID *id, bool create); static DepsgraphStatsComponent *get_component_stats(DepsgraphStatsID *id_stats, - const string &name, + const char *name, bool create); static DepsgraphStatsComponent *get_component_stats(ID *id, - const string &name, + const char *name, bool create) { return get_component_stats(get_id_stats(id, create), name, create); diff --git a/source/blender/depsgraph/intern/nodes/deg_node.cc b/source/blender/depsgraph/intern/nodes/deg_node.cc index eb408f293de..57b25c10670 100644 --- a/source/blender/depsgraph/intern/nodes/deg_node.cc +++ b/source/blender/depsgraph/intern/nodes/deg_node.cc @@ -31,7 +31,7 @@ #include "intern/nodes/deg_node.h" #include <stdio.h> -#include <string.h> +#include <cstring> /* required for STREQ later on. */ #include "BLI_utildefines.h" #include "BLI_ghash.h" @@ -72,7 +72,7 @@ DepsNode::TypeInfo::TypeInfo(eDepsNode_Type type, const char *tname) DepsNode::DepsNode() { - name[0] = '\0'; + name = ""; } DepsNode::~DepsNode() @@ -122,7 +122,7 @@ RootDepsNode::~RootDepsNode() OBJECT_GUARDED_DELETE(time_source, TimeSourceDepsNode); } -TimeSourceDepsNode *RootDepsNode::add_time_source(const string &name) +TimeSourceDepsNode *RootDepsNode::add_time_source(const char *name) { if (!time_source) { DepsNodeFactory *factory = deg_get_node_factory(DEPSNODE_TYPE_TIMESOURCE); @@ -142,12 +142,24 @@ static DepsNodeFactoryImpl<TimeSourceDepsNode> DNTI_TIMESOURCE; /* ID Node ================================================ */ +IDDepsNode::ComponentIDKey::ComponentIDKey(eDepsNode_Type type, + const char *name) + : type(type), name(name) +{ +} + +bool IDDepsNode::ComponentIDKey::operator== (const ComponentIDKey &other) const +{ + return type == other.type && + STREQ(name, other.name); +} + static unsigned int id_deps_node_hash_key(const void *key_v) { const IDDepsNode::ComponentIDKey *key = reinterpret_cast<const IDDepsNode::ComponentIDKey *>(key_v); return hash_combine(BLI_ghashutil_uinthash(key->type), - BLI_ghashutil_strhash_p(key->name.c_str())); + BLI_ghashutil_strhash_p(key->name)); } static bool id_deps_node_hash_key_cmp(const void *a, const void *b) @@ -173,7 +185,7 @@ static void id_deps_node_hash_value_free(void *value_v) } /* Initialize 'id' node - from pointer data given. */ -void IDDepsNode::init(const ID *id, const string &UNUSED(subdata)) +void IDDepsNode::init(const ID *id, const char *UNUSED(subdata)) { /* Store ID-pointer. */ BLI_assert(id != NULL); @@ -204,14 +216,14 @@ IDDepsNode::~IDDepsNode() } ComponentDepsNode *IDDepsNode::find_component(eDepsNode_Type type, - const string &name) const + const char *name) const { ComponentIDKey key(type, name); return reinterpret_cast<ComponentDepsNode *>(BLI_ghash_lookup(components, &key)); } ComponentDepsNode *IDDepsNode::add_component(eDepsNode_Type type, - const string &name) + const char *name) { ComponentDepsNode *comp_node = find_component(type, name); if (!comp_node) { @@ -226,7 +238,7 @@ ComponentDepsNode *IDDepsNode::add_component(eDepsNode_Type type, return comp_node; } -void IDDepsNode::remove_component(eDepsNode_Type type, const string &name) +void IDDepsNode::remove_component(eDepsNode_Type type, const char *name) { ComponentDepsNode *comp_node = find_component(type, name); if (comp_node) { @@ -281,7 +293,7 @@ static DepsNodeFactoryImpl<IDDepsNode> DNTI_ID_REF; /* Subgraph Node ========================================== */ /* Initialize 'subgraph' node - from pointer data given. */ -void SubgraphDepsNode::init(const ID *id, const string &UNUSED(subdata)) +void SubgraphDepsNode::init(const ID *id, const char *UNUSED(subdata)) { /* Store ID-ref if provided. */ this->root_id = (ID *)id; diff --git a/source/blender/depsgraph/intern/nodes/deg_node.h b/source/blender/depsgraph/intern/nodes/deg_node.h index b2262c4bd12..7c2f53840b6 100644 --- a/source/blender/depsgraph/intern/nodes/deg_node.h +++ b/source/blender/depsgraph/intern/nodes/deg_node.h @@ -32,6 +32,8 @@ #include "intern/depsgraph_types.h" +#include "BLI_utildefines.h" + struct ID; struct GHash; struct Scene; @@ -57,7 +59,7 @@ struct DepsNode { }; /* Identifier - mainly for debugging purposes. */ - string name; + const char *name; /* Structural type of node. */ eDepsNode_Type type; @@ -78,8 +80,9 @@ struct DepsNode { /* Nodes which depend on this one. */ Relations outlinks; - /* Generic tag for traversal algorithms */ + /* Generic tags for traversal algorithms. */ int done; + int tag; /* Methods. */ @@ -90,7 +93,7 @@ struct DepsNode { string full_identifier() const; virtual void init(const ID * /*id*/, - const string &/*subdata*/) {} + const char * /*subdata*/) {} virtual void tag_update(Depsgraph * /*graph*/) {} @@ -129,7 +132,7 @@ struct RootDepsNode : public DepsNode { RootDepsNode(); ~RootDepsNode(); - TimeSourceDepsNode *add_time_source(const string &name = ""); + TimeSourceDepsNode *add_time_source(const char *name = ""); /* scene that this corresponds to */ Scene *scene; @@ -143,26 +146,21 @@ struct RootDepsNode : public DepsNode { /* ID-Block Reference */ struct IDDepsNode : public DepsNode { struct ComponentIDKey { - ComponentIDKey(eDepsNode_Type type, const string &name = "") - : type(type), name(name) {} - - bool operator== (const ComponentIDKey &other) const - { - return type == other.type && name == other.name; - } + ComponentIDKey(eDepsNode_Type type, const char *name = ""); + bool operator==(const ComponentIDKey &other) const; eDepsNode_Type type; - string name; + const char *name; }; - void init(const ID *id, const string &subdata); + void init(const ID *id, const char *subdata); ~IDDepsNode(); ComponentDepsNode *find_component(eDepsNode_Type type, - const string &name = "") const; + const char *name = "") const; ComponentDepsNode *add_component(eDepsNode_Type type, - const string &name = ""); - void remove_component(eDepsNode_Type type, const string &name = ""); + const char *name = ""); + void remove_component(eDepsNode_Type type, const char *name = ""); void clear_components(); void tag_update(Depsgraph *graph); @@ -189,7 +187,7 @@ struct IDDepsNode : public DepsNode { /* Subgraph Reference. */ struct SubgraphDepsNode : public DepsNode { - void init(const ID *id, const string &subdata); + void init(const ID *id, const char *subdata); ~SubgraphDepsNode(); /* Instanced graph. */ diff --git a/source/blender/depsgraph/intern/nodes/deg_node_component.cc b/source/blender/depsgraph/intern/nodes/deg_node_component.cc index 01f33b6368b..06f91ac7fdc 100644 --- a/source/blender/depsgraph/intern/nodes/deg_node_component.cc +++ b/source/blender/depsgraph/intern/nodes/deg_node_component.cc @@ -31,7 +31,7 @@ #include "intern/nodes/deg_node_component.h" #include <stdio.h> -#include <string.h> +#include <cstring> /* required for STREQ later on. */ extern "C" { #include "BLI_utildefines.h" @@ -53,12 +53,50 @@ namespace DEG { /* Standard Component Methods ============================= */ +ComponentDepsNode::OperationIDKey::OperationIDKey() + : opcode(DEG_OPCODE_OPERATION), + name(""), + name_tag(-1) +{ +} + +ComponentDepsNode::OperationIDKey::OperationIDKey(eDepsOperation_Code opcode) + : opcode(opcode), + name(""), + name_tag(-1) +{ +} + +ComponentDepsNode::OperationIDKey::OperationIDKey(eDepsOperation_Code opcode, + const char *name, + int name_tag) + : opcode(opcode), + name(name), + name_tag(name_tag) +{ +} + +string ComponentDepsNode::OperationIDKey::identifier() const +{ + char codebuf[5]; + BLI_snprintf(codebuf, sizeof(codebuf), "%d", opcode); + return string("OperationIDKey(") + codebuf + ", " + name + ")"; +} + +bool ComponentDepsNode::OperationIDKey::operator==( + const OperationIDKey &other) const +{ + return (opcode == other.opcode) && + (STREQ(name, other.name)) && + (name_tag == other.name_tag); +} + static unsigned int comp_node_hash_key(const void *key_v) { const ComponentDepsNode::OperationIDKey *key = reinterpret_cast<const ComponentDepsNode::OperationIDKey *>(key_v); return hash_combine(BLI_ghashutil_uinthash(key->opcode), - BLI_ghashutil_strhash_p(key->name.c_str())); + BLI_ghashutil_strhash_p(key->name)); } static bool comp_node_hash_key_cmp(const void *a, const void *b) @@ -95,7 +133,7 @@ ComponentDepsNode::ComponentDepsNode() : /* Initialize 'component' node - from pointer data given */ void ComponentDepsNode::init(const ID * /*id*/, - const string & /*subdata*/) + const char * /*subdata*/) { /* hook up eval context? */ // XXX: maybe this needs a special API? @@ -114,7 +152,7 @@ ComponentDepsNode::~ComponentDepsNode() string ComponentDepsNode::identifier() const { - string &idname = this->owner->name; + string idname = this->owner->name; char typebuf[16]; sprintf(typebuf, "(%d)", type); @@ -139,9 +177,11 @@ OperationDepsNode *ComponentDepsNode::find_operation(OperationIDKey key) const } } -OperationDepsNode *ComponentDepsNode::find_operation(eDepsOperation_Code opcode, const string &name) const +OperationDepsNode *ComponentDepsNode::find_operation(eDepsOperation_Code opcode, + const char *name, + int name_tag) const { - OperationIDKey key(opcode, name); + OperationIDKey key(opcode, name, name_tag); return find_operation(key); } @@ -151,21 +191,26 @@ OperationDepsNode *ComponentDepsNode::has_operation(OperationIDKey key) const } OperationDepsNode *ComponentDepsNode::has_operation(eDepsOperation_Code opcode, - const string &name) const + const char *name, + int name_tag) const { - OperationIDKey key(opcode, name); + OperationIDKey key(opcode, name, name_tag); return has_operation(key); } -OperationDepsNode *ComponentDepsNode::add_operation(eDepsOperation_Type optype, DepsEvalOperationCb op, eDepsOperation_Code opcode, const string &name) +OperationDepsNode *ComponentDepsNode::add_operation(eDepsOperation_Type optype, + DepsEvalOperationCb op, + eDepsOperation_Code opcode, + const char *name, + int name_tag) { - OperationDepsNode *op_node = has_operation(opcode, name); + OperationDepsNode *op_node = has_operation(opcode, name, name_tag); if (!op_node) { DepsNodeFactory *factory = deg_get_node_factory(DEPSNODE_TYPE_OPERATION); op_node = (OperationDepsNode *)factory->create_node(this->owner->id, "", name); /* register opnode in this component's operation set */ - OperationIDKey *key = OBJECT_GUARDED_NEW(OperationIDKey, opcode, name); + OperationIDKey *key = OBJECT_GUARDED_NEW(OperationIDKey, opcode, name, name_tag); BLI_ghash_insert(operations_map, key, op_node); /* set as entry/exit node of component (if appropriate) */ @@ -197,16 +242,6 @@ OperationDepsNode *ComponentDepsNode::add_operation(eDepsOperation_Type optype, return op_node; } -void ComponentDepsNode::remove_operation(eDepsOperation_Code opcode, const string &name) -{ - /* unregister */ - OperationIDKey key(opcode, name); - BLI_ghash_remove(operations_map, - &key, - comp_node_hash_key_free, - comp_node_hash_key_free); -} - void ComponentDepsNode::clear_operations() { if (operations_map != NULL) { @@ -337,7 +372,7 @@ static DepsNodeFactoryImpl<PoseComponentDepsNode> DNTI_EVAL_POSE; /* Bone Component ========================================= */ /* Initialize 'bone component' node - from pointer data given */ -void BoneComponentDepsNode::init(const ID *id, const string &subdata) +void BoneComponentDepsNode::init(const ID *id, const char *subdata) { /* generic component-node... */ ComponentDepsNode::init(id, subdata); @@ -350,7 +385,7 @@ void BoneComponentDepsNode::init(const ID *id, const string &subdata) /* bone-specific node data */ Object *ob = (Object *)id; - this->pchan = BKE_pose_channel_find_name(ob->pose, subdata.c_str()); + this->pchan = BKE_pose_channel_find_name(ob->pose, subdata); } DEG_DEPSNODE_DEFINE(BoneComponentDepsNode, DEPSNODE_TYPE_BONE, "Bone Component"); diff --git a/source/blender/depsgraph/intern/nodes/deg_node_component.h b/source/blender/depsgraph/intern/nodes/deg_node_component.h index 7dec8eaaa90..969771a29c9 100644 --- a/source/blender/depsgraph/intern/nodes/deg_node_component.h +++ b/source/blender/depsgraph/intern/nodes/deg_node_component.h @@ -53,50 +53,38 @@ struct ComponentDepsNode : public DepsNode { struct OperationIDKey { eDepsOperation_Code opcode; - string name; - - - OperationIDKey() : - opcode(DEG_OPCODE_OPERATION), name("") - {} - OperationIDKey(eDepsOperation_Code opcode) : - opcode(opcode), name("") - {} - OperationIDKey(eDepsOperation_Code opcode, const string &name) : - opcode(opcode), name(name) - {} - - string identifier() const - { - char codebuf[5]; - BLI_snprintf(codebuf, sizeof(codebuf), "%d", opcode); - - return string("OperationIDKey(") + codebuf + ", " + name + ")"; - } - - bool operator==(const OperationIDKey &other) const - { - return (opcode == other.opcode) && (name == other.name); - } + const char *name; + int name_tag; + + OperationIDKey(); + OperationIDKey(eDepsOperation_Code opcode); + OperationIDKey(eDepsOperation_Code opcode, + const char *name, + int name_tag); + + string identifier() const; + bool operator==(const OperationIDKey &other) const; }; /* Typedef for container of operations */ ComponentDepsNode(); ~ComponentDepsNode(); - void init(const ID *id, const string &subdata); + void init(const ID *id, const char *subdata); string identifier() const; /* Find an existing operation, will throw an assert() if it does not exist. */ OperationDepsNode *find_operation(OperationIDKey key) const; OperationDepsNode *find_operation(eDepsOperation_Code opcode, - const string &name) const; + const char *name, + int name_tag) const; /* Check operation exists and return it. */ OperationDepsNode *has_operation(OperationIDKey key) const; OperationDepsNode *has_operation(eDepsOperation_Code opcode, - const string &name) const; + const char *name, + int name_tag) const; /** * Create a new node for representing an operation and add this to graph @@ -114,9 +102,9 @@ struct ComponentDepsNode : public DepsNode { OperationDepsNode *add_operation(eDepsOperation_Type optype, DepsEvalOperationCb op, eDepsOperation_Code opcode, - const string &name); + const char *name, + int name_tag); - void remove_operation(eDepsOperation_Code opcode, const string &name); void clear_operations(); void tag_update(Depsgraph *graph); @@ -194,7 +182,7 @@ struct PoseComponentDepsNode : public ComponentDepsNode { /* Bone Component */ struct BoneComponentDepsNode : public ComponentDepsNode { - void init(const ID *id, const string &subdata); + void init(const ID *id, const char *subdata); struct bPoseChannel *pchan; /* the bone that this component represents */ diff --git a/source/blender/depsgraph/intern/nodes/deg_node_operation.cc b/source/blender/depsgraph/intern/nodes/deg_node_operation.cc index 5847af29ac2..9eed4dfe8d8 100644 --- a/source/blender/depsgraph/intern/nodes/deg_node_operation.cc +++ b/source/blender/depsgraph/intern/nodes/deg_node_operation.cc @@ -68,7 +68,7 @@ string OperationDepsNode::full_identifier() const { string owner_str = ""; if (owner->type == DEPSNODE_TYPE_BONE) { - owner_str = owner->owner->name + "." + owner->name; + owner_str = string(owner->owner->name) + "." + owner->name; } else { owner_str = owner->owner->name; diff --git a/source/blender/editors/io/io_collada.c b/source/blender/editors/io/io_collada.c index 8659100df87..baae92f962e 100644 --- a/source/blender/editors/io/io_collada.c +++ b/source/blender/editors/io/io_collada.c @@ -305,7 +305,6 @@ void WM_OT_collada_export(wmOperatorType *ot) static EnumPropertyItem prop_bc_export_transformation_type[] = { {BC_TRANSFORMATION_TYPE_MATRIX, "matrix", 0, "Matrix", "Use <matrix> to specify transformations"}, {BC_TRANSFORMATION_TYPE_TRANSROTLOC, "transrotloc", 0, "TransRotLoc", "Use <translate>, <rotate>, <scale> to specify transformations"}, - {BC_TRANSFORMATION_TYPE_BOTH, "both", 0, "Both", "Use <matrix> AND <translate>, <rotate>, <scale> to specify transformations"}, {0, NULL, 0, NULL, NULL} }; diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index 4482a071c91..6e973740f7c 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -1306,7 +1306,9 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base, if (use_hierarchy || use_base_parent) { dupli_gh = BLI_ghash_ptr_new(__func__); - parent_gh = BLI_ghash_new(dupliobject_hash, dupliobject_cmp, __func__); + if (use_hierarchy) { + parent_gh = BLI_ghash_new(dupliobject_hash, dupliobject_cmp, __func__); + } } for (dob = lb->first; dob; dob = dob->next) { @@ -1343,10 +1345,17 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base, copy_m4_m4(ob->obmat, dob->mat); BKE_object_apply_mat4(ob, ob->obmat, false, false); - if (dupli_gh) + if (dupli_gh) { BLI_ghash_insert(dupli_gh, dob, ob); - if (parent_gh) - BLI_ghash_insert(parent_gh, dob, ob); + } + if (parent_gh) { + void **val; + /* Due to nature of hash/comparison of this ghash, a lot of duplis may be considered as 'the same', + * this avoids trying to insert same key several time and raise asserts in debug builds... */ + if (!BLI_ghash_ensure_p(parent_gh, dob, &val)) { + *val = ob; + } + } DAG_id_tag_update(&ob->id, OB_RECALC_DATA); } diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index b593ac0f2e8..a3ff8dcb676 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -1739,10 +1739,16 @@ static void single_object_users(Main *bmain, Scene *scene, View3D *v3d, const in clear_sca_new_poins(); /* sensor/contr/act */ - /* newid may still have some trash from Outliner tree building, - * so clear that first to avoid errors [#26002] */ - for (ob = bmain->object.first; ob; ob = ob->id.next) - ob->id.newid = NULL; + /* newid may still have some trash from Outliner tree building, so clear that first to avoid errors, see T26002. + * We have to clear whole datablocks, not only Object one may be accessed here, see T49905. */ + ListBase *lbarray[MAX_LIBARRAY]; + int a = set_listbasepointers(bmain, lbarray); + while (a--) { + ListBase *lb = lbarray[a]; + for (ID *id = lb->first; id; id = id->next) { + id->newid = NULL; + } + } /* duplicate (must set newid) */ for (base = FIRSTBASE; base; base = base->next) { diff --git a/source/blender/makesdna/DNA_rigidbody_types.h b/source/blender/makesdna/DNA_rigidbody_types.h index 934028f2e5f..72805c7acb4 100644 --- a/source/blender/makesdna/DNA_rigidbody_types.h +++ b/source/blender/makesdna/DNA_rigidbody_types.h @@ -223,10 +223,16 @@ typedef struct RigidBodyCon { float spring_stiffness_x; float spring_stiffness_y; float spring_stiffness_z; + float spring_stiffness_ang_x; + float spring_stiffness_ang_y; + float spring_stiffness_ang_z; /* amount of velocity lost over time */ float spring_damping_x; float spring_damping_y; float spring_damping_z; + float spring_damping_ang_x; + float spring_damping_ang_y; + float spring_damping_ang_z; /* motor settings */ float motor_lin_target_velocity; /* linear velocity the motor tries to hold */ @@ -292,7 +298,11 @@ typedef enum eRigidBodyCon_Flag { RBC_FLAG_USE_SPRING_Z = (1 << 13), /* motors */ RBC_FLAG_USE_MOTOR_LIN = (1 << 14), - RBC_FLAG_USE_MOTOR_ANG = (1 << 15) + RBC_FLAG_USE_MOTOR_ANG = (1 << 15), + /* angular springs */ + RBC_FLAG_USE_SPRING_ANG_X = (1 << 16), + RBC_FLAG_USE_SPRING_ANG_Y = (1 << 17), + RBC_FLAG_USE_SPRING_ANG_Z = (1 << 18) } eRigidBodyCon_Flag; /* ******************************** */ diff --git a/source/blender/makesrna/intern/rna_rigidbody.c b/source/blender/makesrna/intern/rna_rigidbody.c index 074a24ad01f..45ca865ad78 100644 --- a/source/blender/makesrna/intern/rna_rigidbody.c +++ b/source/blender/makesrna/intern/rna_rigidbody.c @@ -504,6 +504,45 @@ static void rna_RigidBodyCon_spring_stiffness_z_set(PointerRNA *ptr, float value #endif } +static void rna_RigidBodyCon_spring_stiffness_ang_x_set(PointerRNA *ptr, float value) +{ + RigidBodyCon *rbc = (RigidBodyCon *)ptr->data; + + rbc->spring_stiffness_ang_x = value; + +#ifdef WITH_BULLET + if (rbc->physics_constraint && rbc->type == RBC_TYPE_6DOF_SPRING && (rbc->flag & RBC_FLAG_USE_SPRING_ANG_X)) { + RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_X, value); + } +#endif +} + +static void rna_RigidBodyCon_spring_stiffness_ang_y_set(PointerRNA *ptr, float value) +{ + RigidBodyCon *rbc = (RigidBodyCon *)ptr->data; + + rbc->spring_stiffness_ang_y = value; + +#ifdef WITH_BULLET + if (rbc->physics_constraint && rbc->type == RBC_TYPE_6DOF_SPRING && (rbc->flag & RBC_FLAG_USE_SPRING_ANG_Y)) { + RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_Y, value); + } +#endif +} + +static void rna_RigidBodyCon_spring_stiffness_ang_z_set(PointerRNA *ptr, float value) +{ + RigidBodyCon *rbc = (RigidBodyCon *)ptr->data; + + rbc->spring_stiffness_ang_z = value; + +#ifdef WITH_BULLET + if (rbc->physics_constraint && rbc->type == RBC_TYPE_6DOF_SPRING && (rbc->flag & RBC_FLAG_USE_SPRING_ANG_Z)) { + RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_Z, value); + } +#endif +} + static void rna_RigidBodyCon_spring_damping_x_set(PointerRNA *ptr, float value) { RigidBodyCon *rbc = (RigidBodyCon *)ptr->data; @@ -541,6 +580,43 @@ static void rna_RigidBodyCon_spring_damping_z_set(PointerRNA *ptr, float value) #endif } +static void rna_RigidBodyCon_spring_damping_ang_x_set(PointerRNA *ptr, float value) +{ + RigidBodyCon *rbc = (RigidBodyCon *)ptr->data; + + rbc->spring_damping_ang_x = value; + +#ifdef WITH_BULLET + if (rbc->physics_constraint && rbc->type == RBC_TYPE_6DOF_SPRING && (rbc->flag & RBC_FLAG_USE_SPRING_ANG_X)) { + RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_X, value); + } +#endif +} + +static void rna_RigidBodyCon_spring_damping_ang_y_set(PointerRNA *ptr, float value) +{ + RigidBodyCon *rbc = (RigidBodyCon *)ptr->data; + + rbc->spring_damping_ang_y = value; +#ifdef WITH_BULLET + if (rbc->physics_constraint && rbc->type == RBC_TYPE_6DOF_SPRING && (rbc->flag & RBC_FLAG_USE_SPRING_ANG_Y)) { + RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_Y, value); + } +#endif +} + +static void rna_RigidBodyCon_spring_damping_ang_z_set(PointerRNA *ptr, float value) +{ + RigidBodyCon *rbc = (RigidBodyCon *)ptr->data; + + rbc->spring_damping_ang_z = value; +#ifdef WITH_BULLET + if (rbc->physics_constraint && rbc->type == RBC_TYPE_6DOF_SPRING && (rbc->flag & RBC_FLAG_USE_SPRING_ANG_Z)) { + RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_Z, value); + } +#endif +} + static void rna_RigidBodyCon_motor_lin_max_impulse_set(PointerRNA *ptr, float value) { RigidBodyCon *rbc = (RigidBodyCon *)ptr->data; @@ -1052,6 +1128,21 @@ static void rna_def_rigidbody_constraint(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Z Spring", "Enable spring on Z axis"); RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset"); + prop = RNA_def_property(srna, "use_spring_ang_x", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", RBC_FLAG_USE_SPRING_ANG_X); + RNA_def_property_ui_text(prop, "X Angle Spring", "Enable spring on X rotational axis"); + RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset"); + + prop = RNA_def_property(srna, "use_spring_ang_y", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", RBC_FLAG_USE_SPRING_ANG_Y); + RNA_def_property_ui_text(prop, "Y Angle Spring", "Enable spring on Y rotational axis"); + RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset"); + + prop = RNA_def_property(srna, "use_spring_ang_z", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", RBC_FLAG_USE_SPRING_ANG_Z); + RNA_def_property_ui_text(prop, "Z Angle Spring", "Enable spring on Z rotational axis"); + RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset"); + prop = RNA_def_property(srna, "use_motor_lin", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", RBC_FLAG_USE_MOTOR_LIN); RNA_def_property_boolean_funcs(prop, NULL, "rna_RigidBodyCon_use_motor_lin_set"); @@ -1169,6 +1260,33 @@ static void rna_def_rigidbody_constraint(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Z Axis Stiffness", "Stiffness on the Z axis"); RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset"); + prop = RNA_def_property(srna, "spring_stiffness_ang_x", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "spring_stiffness_ang_x"); + RNA_def_property_range(prop, 0.0f, FLT_MAX); + RNA_def_property_ui_range(prop, 0.0f, 100.0f, 1, 3); + RNA_def_property_float_default(prop, 10.0f); + RNA_def_property_float_funcs(prop, NULL, "rna_RigidBodyCon_spring_stiffness_ang_x_set", NULL); + RNA_def_property_ui_text(prop, "X Angle Stiffness", "Stiffness on the X rotational axis"); + RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset"); + + prop = RNA_def_property(srna, "spring_stiffness_ang_y", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "spring_stiffness_ang_y"); + RNA_def_property_range(prop, 0.0f, FLT_MAX); + RNA_def_property_ui_range(prop, 0.0f, 100.0f, 1, 3); + RNA_def_property_float_default(prop, 10.0f); + RNA_def_property_float_funcs(prop, NULL, "rna_RigidBodyCon_spring_stiffness_ang_y_set", NULL); + RNA_def_property_ui_text(prop, "Y Angle Stiffness", "Stiffness on the Y rotational axis"); + RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset"); + + prop = RNA_def_property(srna, "spring_stiffness_ang_z", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "spring_stiffness_ang_z"); + RNA_def_property_range(prop, 0.0f, FLT_MAX); + RNA_def_property_ui_range(prop, 0.0f, 100.0f, 1, 3); + RNA_def_property_float_default(prop, 10.0f); + RNA_def_property_float_funcs(prop, NULL, "rna_RigidBodyCon_spring_stiffness_ang_z_set", NULL); + RNA_def_property_ui_text(prop, "Z Angle Stiffness", "Stiffness on the Z rotational axis"); + RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset"); + prop = RNA_def_property(srna, "spring_damping_x", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, NULL, "spring_damping_x"); RNA_def_property_range(prop, 0.0f, 1.0f); @@ -1193,6 +1311,30 @@ static void rna_def_rigidbody_constraint(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Damping Z", "Damping on the Z axis"); RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset"); + prop = RNA_def_property(srna, "spring_damping_ang_x", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_sdna(prop, NULL, "spring_damping_ang_x"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_float_default(prop, 0.5f); + RNA_def_property_float_funcs(prop, NULL, "rna_RigidBodyCon_spring_damping_ang_x_set", NULL); + RNA_def_property_ui_text(prop, "Damping X Angle", "Damping on the X rotational axis"); + RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset"); + + prop = RNA_def_property(srna, "spring_damping_ang_y", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_sdna(prop, NULL, "spring_damping_ang_y"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_float_default(prop, 0.5f); + RNA_def_property_float_funcs(prop, NULL, "rna_RigidBodyCon_spring_damping_ang_y_set", NULL); + RNA_def_property_ui_text(prop, "Damping Y Angle", "Damping on the Y rotational axis"); + RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset"); + + prop = RNA_def_property(srna, "spring_damping_ang_z", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_sdna(prop, NULL, "spring_damping_ang_z"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_float_default(prop, 0.5f); + RNA_def_property_float_funcs(prop, NULL, "rna_RigidBodyCon_spring_damping_ang_z_set", NULL); + RNA_def_property_ui_text(prop, "Damping Z Angle", "Damping on the Z rotational axis"); + RNA_def_property_update(prop, NC_OBJECT, "rna_RigidBodyOb_reset"); + prop = RNA_def_property(srna, "motor_lin_target_velocity", PROP_FLOAT, PROP_UNIT_VELOCITY); RNA_def_property_float_sdna(prop, NULL, "motor_lin_target_velocity"); RNA_def_property_range(prop, -FLT_MAX, FLT_MAX); diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index fd5a9d9ecc5..b3aea604926 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -52,15 +52,6 @@ #include "BLT_lang.h" #include "GPU_buffers.h" -#ifdef WITH_CYCLES -static EnumPropertyItem compute_device_type_items[] = { - {USER_COMPUTE_DEVICE_NONE, "NONE", 0, "None", "Don't use compute device"}, - {USER_COMPUTE_DEVICE_CUDA, "CUDA", 0, "CUDA", "Use CUDA for GPU acceleration"}, - {USER_COMPUTE_DEVICE_OPENCL, "OPENCL", 0, "OpenCL", "Use OpenCL for GPU acceleration"}, - { 0, NULL, 0, NULL, NULL} -}; -#endif - #ifdef WITH_OPENSUBDIV static EnumPropertyItem opensubdiv_compute_type_items[] = { {USER_OPENSUBDIV_COMPUTE_NONE, "NONE", 0, "None", ""}, @@ -124,8 +115,6 @@ static EnumPropertyItem rna_enum_language_default_items[] = { #include "UI_interface.h" -#include "CCL_api.h" - #ifdef WITH_OPENSUBDIV # include "opensubdiv_capi.h" #endif @@ -476,78 +465,6 @@ static PointerRNA rna_Theme_space_list_generic_get(PointerRNA *ptr) } -#ifdef WITH_CYCLES -static EnumPropertyItem *rna_userdef_compute_device_type_itemf(bContext *UNUSED(C), PointerRNA *UNUSED(ptr), - PropertyRNA *UNUSED(prop), bool *r_free) -{ - EnumPropertyItem *item = NULL; - int totitem = 0; - - /* add supported device types */ - RNA_enum_items_add_value(&item, &totitem, compute_device_type_items, USER_COMPUTE_DEVICE_NONE); - if (CCL_compute_device_list(0)) - RNA_enum_items_add_value(&item, &totitem, compute_device_type_items, USER_COMPUTE_DEVICE_CUDA); - if (CCL_compute_device_list(1)) - RNA_enum_items_add_value(&item, &totitem, compute_device_type_items, USER_COMPUTE_DEVICE_OPENCL); - - RNA_enum_item_end(&item, &totitem); - *r_free = true; - - return item; -} - -static int rna_userdef_compute_device_get(PointerRNA *UNUSED(ptr)) -{ - if (U.compute_device_type == USER_COMPUTE_DEVICE_NONE) - return 0; - - return U.compute_device_id; -} - -static EnumPropertyItem *rna_userdef_compute_device_itemf(bContext *UNUSED(C), PointerRNA *UNUSED(ptr), - PropertyRNA *UNUSED(prop), bool *r_free) -{ - EnumPropertyItem tmp = {0, "", 0, "", ""}; - EnumPropertyItem *item = NULL; - int totitem = 0; - - if (U.compute_device_type == USER_COMPUTE_DEVICE_NONE) { - /* only add a single CPU device */ - tmp.value = 0; - tmp.name = "CPU"; - tmp.identifier = "CPU"; - RNA_enum_item_add(&item, &totitem, &tmp); - } - else { - /* get device list from cycles. it would be good to make this generic - * once we have more subsystems using opencl, for now this is easiest */ - int opencl = (U.compute_device_type == USER_COMPUTE_DEVICE_OPENCL); - CCLDeviceInfo *devices = CCL_compute_device_list(opencl); - int a; - - if (devices) { - for (a = 0; devices[a].identifier[0]; a++) { - tmp.value = devices[a].value; - tmp.identifier = devices[a].identifier; - tmp.name = devices[a].name; - RNA_enum_item_add(&item, &totitem, &tmp); - } - } - else { - tmp.value = 0; - tmp.name = "CPU"; - tmp.identifier = "CPU"; - RNA_enum_item_add(&item, &totitem, &tmp); - } - } - - RNA_enum_item_end(&item, &totitem); - *r_free = true; - - return item; -} -#endif - #ifdef WITH_OPENSUBDIV static EnumPropertyItem *rna_userdef_opensubdiv_compute_type_itemf(bContext *UNUSED(C), PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free) @@ -3973,13 +3890,6 @@ static void rna_def_userdef_system(BlenderRNA *brna) {0, NULL, 0, NULL, NULL} }; -#ifdef WITH_CYCLES - static EnumPropertyItem compute_device_items[] = { - {0, "CPU", 0, "CPU", ""}, - { 0, NULL, 0, NULL, NULL} - }; -#endif - static EnumPropertyItem image_draw_methods[] = { {IMAGE_DRAW_METHOD_2DTEXTURE, "2DTEXTURE", 0, "2D Texture", "Use CPU for display transform and draw image with 2D texture"}, {IMAGE_DRAW_METHOD_GLSL, "GLSL", 0, "GLSL", "Use GLSL shaders for display transform and draw image with 2D texture"}, @@ -4271,23 +4181,6 @@ static void rna_def_userdef_system(BlenderRNA *brna) "Draw tool/property regions over the main region, when using Triple Buffer"); RNA_def_property_update(prop, 0, "rna_userdef_dpi_update"); -#ifdef WITH_CYCLES - prop = RNA_def_property(srna, "compute_device_type", PROP_ENUM, PROP_NONE); - RNA_def_property_flag(prop, PROP_ENUM_NO_CONTEXT); - RNA_def_property_enum_sdna(prop, NULL, "compute_device_type"); - RNA_def_property_enum_items(prop, compute_device_type_items); - RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_userdef_compute_device_type_itemf"); - RNA_def_property_ui_text(prop, "Compute Device Type", "Device to use for computation (rendering with Cycles)"); - RNA_def_property_update(prop, NC_SPACE | ND_SPACE_PROPERTIES, NULL); - - prop = RNA_def_property(srna, "compute_device", PROP_ENUM, PROP_NONE); - RNA_def_property_flag(prop, PROP_ENUM_NO_CONTEXT); - RNA_def_property_enum_sdna(prop, NULL, "compute_device_id"); - RNA_def_property_enum_items(prop, compute_device_items); - RNA_def_property_enum_funcs(prop, "rna_userdef_compute_device_get", NULL, "rna_userdef_compute_device_itemf"); - RNA_def_property_ui_text(prop, "Compute Device", "Device to use for computation"); -#endif - #ifdef WITH_OPENSUBDIV prop = RNA_def_property(srna, "opensubdiv_compute_type", PROP_ENUM, PROP_NONE); RNA_def_property_flag(prop, PROP_ENUM_NO_CONTEXT); diff --git a/source/blender/modifiers/intern/MOD_hook.c b/source/blender/modifiers/intern/MOD_hook.c index 83c4ca7984c..9186b10d8ca 100644 --- a/source/blender/modifiers/intern/MOD_hook.c +++ b/source/blender/modifiers/intern/MOD_hook.c @@ -145,12 +145,9 @@ static void updateDepsgraph(ModifierData *md, HookModifierData *hmd = (HookModifierData *)md; if (hmd->object != NULL) { if (hmd->subtarget[0]) { - DEG_add_bone_relation(node, hmd->object, hmd->subtarget, DEG_OB_COMP_TRANSFORM, "Hook Modifier"); DEG_add_bone_relation(node, hmd->object, hmd->subtarget, DEG_OB_COMP_BONE, "Hook Modifier"); } - else { - DEG_add_object_relation(node, hmd->object, DEG_OB_COMP_TRANSFORM, "Hook Modifier"); - } + DEG_add_object_relation(node, hmd->object, DEG_OB_COMP_TRANSFORM, "Hook Modifier"); } /* We need own transformation as well. */ DEG_add_object_relation(node, ob, DEG_OB_COMP_TRANSFORM, "Hook Modifier"); diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c index d896801357f..15d230f7a0c 100644 --- a/source/blenderplayer/bad_level_call_stubs/stubs.c +++ b/source/blenderplayer/bad_level_call_stubs/stubs.c @@ -142,7 +142,6 @@ struct wmWindowManager; # pragma GCC diagnostic ignored "-Wunused-parameter" #endif -#include "../../intern/cycles/blender/CCL_api.h" #include "../../intern/dualcon/dualcon.h" #include "../../intern/elbeem/extern/elbeem.h" #include "../blender/blenkernel/BKE_modifier.h" @@ -767,10 +766,6 @@ void *dualcon(const DualConInput *input_mesh, float scale, int depth) RET_ZERO -/* intern/cycles */ -struct CCLDeviceInfo; -struct CCLDeviceInfo *CCL_compute_device_list(int opencl) RET_NULL - /* compositor */ void COM_execute(RenderData *rd, Scene *scene, bNodeTree *editingtree, int rendering, const ColorManagedViewSettings *viewSettings, const ColorManagedDisplaySettings *displaySettings, diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt index f65688e1304..10af0d5489e 100644 --- a/source/creator/CMakeLists.txt +++ b/source/creator/CMakeLists.txt @@ -1153,13 +1153,12 @@ if(WIN32 AND NOT WITH_PYTHON_MODULE) COMPONENT Blender DESTINATION "." ) - + if(CMAKE_CL_64) + set(_WIN_PLATFORM x64) + else() + set(_WIN_PLATFORM x86) + endif() if(MSVC12_REDIST_DIR) - if(CMAKE_CL_64) - set(_WIN_PLATFORM x64) - else() - set(_WIN_PLATFORM x86) - endif() install( FILES ${MSVC12_REDIST_DIR}/${_WIN_PLATFORM}/Microsoft.VC120.CRT/msvcp120.dll @@ -1173,4 +1172,51 @@ if(WIN32 AND NOT WITH_PYTHON_MODULE) ) endif() endif() + + if(MSVC14_REDIST_DIR) + set(KITSDIRx86 "$ENV{${ProgramFilesX86_NAME}}/Windows Kits/10/") + set(KITSDIR "$ENV{ProgramFiles}/Windows Kits/10/") + if(IS_DIRECTORY ${KITSDIR}) + set(KITSPATH "${KITSDIR}/Redist/ucrt/DLLs/${_WIN_PLATFORM}") + else() + if(IS_DIRECTORY ${KITSDIRx86}) + set(KITSPATH "${KITSDIRx86}/Redist/ucrt/DLLs/${_WIN_PLATFORM}") + else() + message(FATAL_ERROR "Windows 10 SDK directory not found") + endif() + endif() + + install( + FILES + ${KITSPATH}/api-ms-win-core-file-l1-2-0.dll + ${KITSPATH}/api-ms-win-core-file-l2-1-0.dll + ${KITSPATH}/api-ms-win-core-localization-l1-2-0.dll + ${KITSPATH}/api-ms-win-core-processthreads-l1-1-0.dll + ${KITSPATH}/api-ms-win-core-processthreads-l1-1-1.dll + ${KITSPATH}/api-ms-win-core-synch-l1-1-0.dll + ${KITSPATH}/api-ms-win-core-synch-l1-2-0.dll + ${KITSPATH}/api-ms-win-core-timezone-l1-1-0.dll + ${KITSPATH}/api-ms-win-crt-conio-l1-1-0.dll + ${KITSPATH}/api-ms-win-crt-convert-l1-1-0.dll + ${KITSPATH}/api-ms-win-crt-environment-l1-1-0.dll + ${KITSPATH}/api-ms-win-crt-filesystem-l1-1-0.dll + ${KITSPATH}/api-ms-win-crt-heap-l1-1-0.dll + ${KITSPATH}/api-ms-win-crt-locale-l1-1-0.dll + ${KITSPATH}/api-ms-win-crt-math-l1-1-0.dll + ${KITSPATH}/api-ms-win-crt-process-l1-1-0.dll + ${KITSPATH}/api-ms-win-crt-runtime-l1-1-0.dll + ${KITSPATH}/api-ms-win-crt-stdio-l1-1-0.dll + ${KITSPATH}/api-ms-win-crt-string-l1-1-0.dll + ${KITSPATH}/api-ms-win-crt-time-l1-1-0.dll + ${KITSPATH}/ucrtbase.dll + ${MSVC14_REDIST_DIR}/${_WIN_PLATFORM}/Microsoft.VC140.CRT/vcruntime140.dll + DESTINATION "." + ) + if(WITH_OPENMP) + install( + FILES ${MSVC14_REDIST_DIR}/${_WIN_PLATFORM}/Microsoft.VC140.OpenMP/vcomp140.dll + DESTINATION "." + ) + endif() + endif() endif() diff --git a/tests/python/CMakeLists.txt b/tests/python/CMakeLists.txt index 8487c6a2094..a29b612e0ef 100644 --- a/tests/python/CMakeLists.txt +++ b/tests/python/CMakeLists.txt @@ -130,7 +130,7 @@ add_test(export_obj_cube ${TEST_BLENDER_EXE} --run={'FINISHED'}&bpy.ops.export_scene.obj\(filepath='${TEST_OUT_DIR}/export_obj_cube.obj',use_selection=False\) --md5_source=${TEST_OUT_DIR}/export_obj_cube.obj --md5_source=${TEST_OUT_DIR}/export_obj_cube.mtl - --md5=826f74e6b7a2128b0b61a52071ada36e --md5_method=FILE + --md5=e80660437ad9bfe082849641c361a233 --md5_method=FILE ) add_test(export_obj_nurbs ${TEST_BLENDER_EXE} |