Merge branch 'master' into blender2.8
Conflicts: intern/cycles/blender/addon/properties.py
This commit is contained in:
commit
c1ba58c44d
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
#
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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. */
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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)";
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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++;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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: {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
5
make.bat
5
make.bat
|
@ -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
|
||||
|
|
|
@ -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'}
|
||||
|
||||
|
|
|
@ -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'}
|
||||
|
|
|
@ -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__)
|
||||
|
|
|
@ -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="")
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{}
|
||||
ComponentKey();
|
||||
ComponentKey(ID *id, eDepsNode_Type type, const char *name = "");
|
||||
|
||||
string 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 + "')";
|
||||
}
|
||||
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();
|
||||
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, 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);
|
||||
OperationKey(ID *id,
|
||||
eDepsNode_Type component_type,
|
||||
const char *component_name,
|
||||
eDepsOperation_Code opcode);
|
||||
|
||||
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(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);
|
||||
}
|
||||
|
|
|
@ -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
|
|
@ -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];
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -100,22 +100,6 @@ struct Depsgraph {
|
|||
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.
|
||||
*
|
||||
|
@ -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();
|
||||
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <cstring>
|
||||
#include <cstring> /* required for memset */
|
||||
#include <queue>
|
||||
|
||||
extern "C" {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -53,50 +53,38 @@ struct ComponentDepsNode : public DepsNode {
|
|||
struct OperationIDKey
|
||||
{
|
||||
eDepsOperation_Code opcode;
|
||||
string name;
|
||||
const char *name;
|
||||
int name_tag;
|
||||
|
||||
OperationIDKey();
|
||||
OperationIDKey(eDepsOperation_Code opcode);
|
||||
OperationIDKey(eDepsOperation_Code opcode,
|
||||
const char *name,
|
||||
int name_tag);
|
||||
|
||||
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);
|
||||
}
|
||||
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 */
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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}
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
||||
/* ******************************** */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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}
|
||||
|
|
Loading…
Reference in New Issue