Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTamito Kajiyama <rd6t-kjym@asahi-net.or.jp>2012-01-08 15:57:53 +0400
committerTamito Kajiyama <rd6t-kjym@asahi-net.or.jp>2012-01-08 15:57:53 +0400
commit76a211d80947a453f594e4cf0a1e0acc6786eddf (patch)
tree59d806409fe72f733bce9c43eb6823b59642c6fd
parentf88501a44d1f519539d056a7d1f240d126a5071a (diff)
parent3dead22c7322cf72ee63a003ba50940abc12e7c9 (diff)
Merged changes in the trunk up to revision 43219.
Conflicts resolved: source/blender/blenkernel/intern/scene.c source/blender/blenloader/intern/readfile.c source/blender/render/intern/source/pipeline.c
-rw-r--r--CMakeLists.txt37
-rw-r--r--build_files/scons/config/win32-mingw-config.py4
-rw-r--r--build_files/scons/config/win32-vc-config.py2
-rw-r--r--build_files/scons/config/win64-vc-config.py2
-rw-r--r--doc/python_api/examples/bpy.types.Operator.4.py2
-rw-r--r--doc/python_api/examples/bpy.types.Operator.5.py1
-rw-r--r--doc/python_api/rst/info_best_practice.rst12
-rw-r--r--doc/python_api/rst/info_quickstart.rst3
-rw-r--r--doc/python_api/rst/info_tips_and_tricks.rst16
-rw-r--r--intern/cycles/app/cycles_server.cpp31
-rw-r--r--intern/cycles/app/cycles_test.cpp54
-rw-r--r--intern/cycles/blender/blender_mesh.cpp5
-rw-r--r--intern/cycles/blender/blender_object.cpp17
-rw-r--r--intern/cycles/blender/blender_session.cpp4
-rw-r--r--intern/cycles/blender/blender_sync.cpp41
-rw-r--r--intern/cycles/device/device.cpp73
-rw-r--r--intern/cycles/device/device.h31
-rw-r--r--intern/cycles/device/device_cpu.cpp14
-rw-r--r--intern/cycles/device/device_cuda.cpp47
-rw-r--r--intern/cycles/device/device_intern.h16
-rw-r--r--intern/cycles/device/device_memory.h6
-rw-r--r--intern/cycles/device/device_multi.cpp142
-rw-r--r--intern/cycles/device/device_network.cpp13
-rw-r--r--intern/cycles/device/device_opencl.cpp82
-rw-r--r--intern/cycles/render/buffers.cpp2
-rw-r--r--intern/cycles/render/session.cpp4
-rw-r--r--intern/cycles/render/session.h6
-rw-r--r--intern/cycles/render/tile.cpp4
-rw-r--r--intern/ghost/CMakeLists.txt7
-rw-r--r--intern/ghost/intern/GHOST_DisplayManagerSDL.cpp8
-rw-r--r--intern/ghost/intern/GHOST_DisplayManagerSDL.h8
-rw-r--r--intern/ghost/intern/GHOST_DisplayManagerX11.cpp76
-rw-r--r--release/scripts/modules/animsys_refactor.py1
-rw-r--r--release/scripts/modules/rna_prop_ui.py8
-rw-r--r--release/scripts/modules/rna_xml.py300
-rw-r--r--release/scripts/modules/sys_info.py2
-rw-r--r--release/scripts/startup/bl_operators/anim.py2
-rw-r--r--release/scripts/startup/bl_operators/clip.py36
-rw-r--r--release/scripts/startup/bl_operators/object_randomize_transform.py2
-rw-r--r--release/scripts/startup/bl_operators/wm.py76
-rw-r--r--release/scripts/startup/bl_ui/properties_data_curve.py21
-rw-r--r--release/scripts/startup/bl_ui/properties_data_mesh.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_game.py10
-rw-r--r--release/scripts/startup/bl_ui/properties_object.py6
-rw-r--r--release/scripts/startup/bl_ui/properties_object_constraint.py6
-rw-r--r--release/scripts/startup/bl_ui/properties_particle.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_render.py15
-rw-r--r--release/scripts/startup/bl_ui/space_clip.py7
-rw-r--r--release/scripts/startup/bl_ui/space_image.py42
-rw-r--r--release/scripts/startup/bl_ui/space_logic.py23
-rw-r--r--release/scripts/startup/bl_ui/space_node.py12
-rw-r--r--release/scripts/startup/bl_ui/space_userpref.py4
-rw-r--r--release/scripts/startup/bl_ui/space_userpref_keymap.py2
-rw-r--r--release/scripts/startup/bl_ui/space_view3d.py33
-rw-r--r--release/scripts/startup/bl_ui/space_view3d_toolbar.py12
-rw-r--r--source/blender/blenfont/intern/blf.c38
-rw-r--r--source/blender/blenkernel/BKE_blender.h2
-rw-r--r--source/blender/blenkernel/BKE_node.h2
-rw-r--r--source/blender/blenkernel/BKE_particle.h3
-rw-r--r--source/blender/blenkernel/BKE_sound.h3
-rw-r--r--source/blender/blenkernel/intern/bvhutils.c2
-rw-r--r--source/blender/blenkernel/intern/constraint.c38
-rw-r--r--source/blender/blenkernel/intern/depsgraph.c5
-rw-r--r--source/blender/blenkernel/intern/mesh.c2
-rw-r--r--source/blender/blenkernel/intern/movieclip.c4
-rw-r--r--source/blender/blenkernel/intern/node.c5
-rw-r--r--source/blender/blenkernel/intern/object.c49
-rw-r--r--source/blender/blenkernel/intern/particle_system.c157
-rw-r--r--source/blender/blenkernel/intern/scene.c2
-rw-r--r--source/blender/blenkernel/intern/seqeffects.c60
-rw-r--r--source/blender/blenkernel/intern/sequencer.c14
-rw-r--r--source/blender/blenkernel/intern/sound.c27
-rw-r--r--source/blender/blenkernel/intern/tracking.c33
-rw-r--r--source/blender/blenloader/intern/readfile.c151
-rw-r--r--source/blender/editors/animation/anim_filter.c8
-rw-r--r--source/blender/editors/animation/anim_ipo_utils.c5
-rw-r--r--source/blender/editors/armature/editarmature.c5
-rw-r--r--source/blender/editors/armature/poselib.c3
-rw-r--r--source/blender/editors/armature/poseobject.c23
-rw-r--r--source/blender/editors/include/ED_object.h3
-rw-r--r--source/blender/editors/interface/interface_draw.c35
-rw-r--r--source/blender/editors/interface/interface_handlers.c83
-rw-r--r--source/blender/editors/interface/interface_templates.c4
-rw-r--r--source/blender/editors/interface/view2d_ops.c9
-rw-r--r--source/blender/editors/mesh/mesh_data.c14
-rw-r--r--source/blender/editors/object/object_edit.c355
-rw-r--r--source/blender/editors/object/object_group.c7
-rw-r--r--source/blender/editors/object/object_shapekey.c15
-rw-r--r--source/blender/editors/object/object_vgroup.c216
-rw-r--r--source/blender/editors/physics/dynamicpaint_ops.c11
-rw-r--r--source/blender/editors/physics/particle_object.c9
-rw-r--r--source/blender/editors/render/render_shading.c11
-rw-r--r--source/blender/editors/screen/screen_ops.c16
-rw-r--r--source/blender/editors/screen/screendump.c11
-rw-r--r--source/blender/editors/space_buttons/buttons_texture.c2
-rw-r--r--source/blender/editors/space_node/node_draw.c20
-rw-r--r--source/blender/editors/space_node/node_edit.c67
-rw-r--r--source/blender/editors/space_node/node_intern.h4
-rw-r--r--source/blender/editors/space_node/node_templates.c2
-rw-r--r--source/blender/editors/space_sequencer/sequencer_edit.c4
-rw-r--r--source/blender/editors/space_view3d/view3d_snap.c3
-rw-r--r--source/blender/gpu/GPU_buffers.h2
-rw-r--r--source/blender/gpu/intern/gpu_buffers.c19
-rw-r--r--source/blender/gpu/intern/gpu_material.c6
-rw-r--r--source/blender/imbuf/IMB_imbuf.h10
-rw-r--r--source/blender/imbuf/intern/anim_movie.c2
-rw-r--r--source/blender/imbuf/intern/divers.c2
-rw-r--r--source/blender/makesdna/DNA_constraint_types.h1
-rw-r--r--source/blender/makesdna/DNA_modifier_types.h31
-rw-r--r--source/blender/makesdna/DNA_node_types.h2
-rw-r--r--source/blender/makesrna/RNA_access.h6
-rw-r--r--source/blender/makesrna/RNA_enum_types.h2
-rw-r--r--source/blender/makesrna/intern/makesrna.c85
-rw-r--r--source/blender/makesrna/intern/rna_constraint.c36
-rw-r--r--source/blender/makesrna/intern/rna_define.c6
-rw-r--r--source/blender/makesrna/intern/rna_modifier.c38
-rw-r--r--source/blender/makesrna/intern/rna_property.c17
-rw-r--r--source/blender/makesrna/intern/rna_scene.c4
-rw-r--r--source/blender/makesrna/intern/rna_screen.c10
-rw-r--r--source/blender/makesrna/intern/rna_tracking.c9
-rw-r--r--source/blender/modifiers/SConscript2
-rw-r--r--source/blender/modifiers/intern/MOD_remesh.c45
-rw-r--r--source/blender/modifiers/intern/MOD_util.c41
-rw-r--r--source/blender/modifiers/intern/MOD_uvproject.c62
-rw-r--r--source/blender/modifiers/intern/MOD_wave.c91
-rw-r--r--source/blender/nodes/composite/node_composite_util.c32
-rw-r--r--source/blender/nodes/intern/node_common.c4
-rw-r--r--source/blender/nodes/shader/node_shader_util.c2
-rw-r--r--source/blender/python/intern/bpy_rna.c47
-rw-r--r--source/blender/python/mathutils/mathutils_Matrix.c73
-rw-r--r--source/blender/python/mathutils/mathutils_Vector.c18
-rw-r--r--source/blender/render/CMakeLists.txt2
-rw-r--r--source/blender/render/extern/include/RE_pipeline.h3
-rw-r--r--source/blender/render/intern/include/render_result.h94
-rw-r--r--source/blender/render/intern/include/renderpipeline.h12
-rw-r--r--source/blender/render/intern/source/external_engine.c25
-rw-r--r--source/blender/render/intern/source/imagetexture.c12
-rw-r--r--source/blender/render/intern/source/pipeline.c1124
-rw-r--r--source/blender/render/intern/source/rayshade.c14
-rw-r--r--source/blender/render/intern/source/render_result.c1024
-rw-r--r--source/blender/render/intern/source/render_texture.c5
-rw-r--r--source/blender/render/intern/source/rendercore.c1
-rw-r--r--source/blender/render/intern/source/zbuf.c1
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c14
-rw-r--r--source/creator/creator.c6
-rw-r--r--source/gameengine/Converter/KX_ConvertProperties.cpp86
-rw-r--r--source/gameengine/GameLogic/CMakeLists.txt4
-rw-r--r--source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp15
-rw-r--r--source/gameengine/Ketsji/KX_FontObject.cpp86
149 files changed, 3699 insertions, 2470 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 40a51f0b452..c124096c575 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -156,6 +156,7 @@ endif()
if(UNIX AND NOT APPLE)
option(WITH_X11_XINPUT "Enable X11 Xinput (tablet support and unicode input)" ON)
+ option(WITH_X11_XF86VMODE "Enable X11 video mode switching" OFF)
option(WITH_BUILTIN_GLEW "Use GLEW OpenGL wrapper library bundled with blender" ON)
option(WITH_XDG_USER_DIRS "Build with XDG Base Directory Specification (only config and documents for now)" OFF)
mark_as_advanced(WITH_XDG_USER_DIRS)
@@ -269,8 +270,8 @@ if(NOT WITH_SDL AND WITH_GHOST_SDL)
message(FATAL_ERROR "WITH_GHOST_SDL requires WITH_SDL to be ON")
endif()
-if(NOT WITH_IMAGE_OPENJPEG AND WITH_IMAGE_REDCODE)
- message(FATAL_ERROR "WITH_IMAGE_REDCODE requires WITH_IMAGE_OPENJPEG")
+if(WITH_IMAGE_REDCODE AND ((NOT WITH_IMAGE_OPENJPEG) OR (NOT WITH_CODEC_FFMPEG)))
+ message(FATAL_ERROR "WITH_IMAGE_REDCODE requires WITH_IMAGE_OPENJPEG and WITH_CODEC_FFMPEG")
endif()
# python module, needs some different options
@@ -584,6 +585,17 @@ if(UNIX AND NOT APPLE)
if(WITH_X11_XINPUT)
set(PLATFORM_LINKLIBS "${PLATFORM_LINKLIBS} ${X11_Xinput_LIB}")
endif()
+
+ if(WITH_X11_XF86VMODE)
+ # XXX, why dont cmake make this available?
+ FIND_LIBRARY(X11_Xxf86vmode_LIB Xxf86vm ${X11_LIB_SEARCH_PATH})
+ mark_as_advanced(X11_Xxf86vmode_LIB)
+ if(X11_Xxf86vmode_LIB)
+ set(PLATFORM_LINKLIBS "${PLATFORM_LINKLIBS} ${X11_Xxf86vmode_LIB}")
+ else()
+ set(WITH_X11_XF86VMODE OFF)
+ endif()
+ endif()
endif()
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
@@ -699,8 +711,8 @@ elseif(WIN32)
add_definitions(/D_CRT_NONSTDC_NO_DEPRECATE /D_CRT_SECURE_NO_DEPRECATE /D_SCL_SECURE_NO_DEPRECATE /D_CONSOLE /D_LIB)
- set(CMAKE_CXX_FLAGS "/nologo /J /W0 /Gd /wd4018 /wd4244 /wd4305 /wd4800 /wd4065 /wd4267 /we4013" CACHE STRING "MSVC MT C++ flags " FORCE)
- set(CMAKE_C_FLAGS "/nologo /J /W0 /Gd /wd4018 /wd4244 /wd4305 /wd4800 /wd4065 /wd4267 /we4013 /EHsc" CACHE STRING "MSVC MT C++ flags " FORCE)
+ set(CMAKE_CXX_FLAGS "/nologo /J /W1 /Gd /wd4018 /wd4244 /wd4305 /wd4800 /wd4065 /wd4267 /we4013" CACHE STRING "MSVC MT C++ flags " FORCE)
+ set(CMAKE_C_FLAGS "/nologo /J /W1 /Gd /wd4018 /wd4244 /wd4305 /wd4800 /wd4065 /wd4267 /we4013 /EHsc" CACHE STRING "MSVC MT C++ flags " FORCE)
if(CMAKE_CL_64)
set(CMAKE_CXX_FLAGS_DEBUG "/Od /Gm /EHsc /RTC1 /MTd /W3 /nologo /Zi /J" CACHE STRING "MSVC MT flags " FORCE)
@@ -1014,9 +1026,13 @@ elseif(WIN32)
set(OPENIMAGEIO_LIBPATH ${OPENIMAGEIO}/lib)
set(OPENIMAGEIO_DEFINITIONS)
endif()
-
+
set(PLATFORM_LINKFLAGS "-Xlinker --stack=2097152")
+ ## DISABLE - causes linking errors
+ ## for re-distrobution, so users dont need mingw installed
+ # set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -static-libgcc -static-libstdc++")
+
endif()
# used in many places so include globally, like OpenGL
@@ -1393,7 +1409,10 @@ if(CMAKE_COMPILER_IS_GNUCC)
# disable because it gives warnings for printf() & friends.
# ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_DOUBLE_PROMOTION -Wdouble-promotion -Wno-error=double-promotion)
- ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_NO_ERROR_UNUSED_BUT_SET_VARIABLE -Wno-error=unused-but-set-variable)
+
+ if(NOT APPLE)
+ ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_NO_ERROR_UNUSED_BUT_SET_VARIABLE -Wno-error=unused-but-set-variable)
+ endif()
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_ALL -Wall)
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_INVALID_OFFSETOF -Wno-invalid-offsetof)
@@ -1405,7 +1424,10 @@ if(CMAKE_COMPILER_IS_GNUCC)
# flags to undo strict flags
ADD_CHECK_C_COMPILER_FLAG(CC_REMOVE_STRICT_FLAGS C_WARN_NO_DEPRECATED_DECLARATIONS -Wno-deprecated-declarations)
ADD_CHECK_C_COMPILER_FLAG(CC_REMOVE_STRICT_FLAGS C_WARN_NO_UNUSED_PARAMETER -Wno-unused-parameter)
- ADD_CHECK_C_COMPILER_FLAG(CC_REMOVE_STRICT_FLAGS C_WARN_NO_UNUSED_BUT_SET_VARIABLE -Wno-unused-but-set-variable)
+
+ if(NOT APPLE)
+ ADD_CHECK_C_COMPILER_FLAG(CC_REMOVE_STRICT_FLAGS C_WARN_NO_ERROR_UNUSED_BUT_SET_VARIABLE -Wno-error=unused-but-set-variable)
+ endif()
elseif(CMAKE_C_COMPILER_ID MATCHES "Intel")
@@ -1541,6 +1563,7 @@ if(FIRST_RUN)
info_cfg_text("System Options:")
info_cfg_option(WITH_INSTALL_PORTABLE)
+ info_cfg_option(WITH_X11_XF86VMODE)
info_cfg_option(WITH_X11_XINPUT)
info_cfg_option(WITH_BUILTIN_GLEW)
diff --git a/build_files/scons/config/win32-mingw-config.py b/build_files/scons/config/win32-mingw-config.py
index e4f8827b7c8..9fac0a31029 100644
--- a/build_files/scons/config/win32-mingw-config.py
+++ b/build_files/scons/config/win32-mingw-config.py
@@ -190,6 +190,10 @@ LLIBS = ['-lshell32', '-lshfolder', '-lgdi32', '-lmsvcrt', '-lwinmm', '-lmingw32
PLATFORM_LINKFLAGS = ['-Xlinker', '--stack=2097152']
+## DISABLED, causes linking errors!
+## for re-distrobution, so users dont need mingw installed
+# PLATFORM_LINKFLAGS += ["-static-libgcc", "-static-libstdc++"]
+
BF_DEBUG = False
BF_DEBUG_CCFLAGS= ['-g', '-D_DEBUG']
diff --git a/build_files/scons/config/win32-vc-config.py b/build_files/scons/config/win32-vc-config.py
index 07cd30b7ee1..2142620f2bf 100644
--- a/build_files/scons/config/win32-vc-config.py
+++ b/build_files/scons/config/win32-vc-config.py
@@ -185,7 +185,7 @@ BF_OPENGL_LIB_STATIC = [ '${BF_OPENGL}/lib/libGL.a', '${BF_OPENGL}/lib/libGLU.a'
CC = 'cl.exe'
CXX = 'cl.exe'
-CCFLAGS = ['/nologo', '/Ob1', '/J', '/W0', '/Gd', '/wd4018', '/wd4244', '/wd4305', '/wd4800', '/wd4065', '/wd4267', '/we4013']
+CCFLAGS = ['/nologo', '/Ob1', '/J', '/W1', '/Gd', '/wd4018', '/wd4244', '/wd4305', '/wd4800', '/wd4065', '/wd4267', '/we4013']
CXXFLAGS = ['/EHsc']
BGE_CXXFLAGS = ['/O2', '/EHsc', '/GR', '/fp:fast', '/arch:SSE']
diff --git a/build_files/scons/config/win64-vc-config.py b/build_files/scons/config/win64-vc-config.py
index 2e7ea6d0034..794f29c5d46 100644
--- a/build_files/scons/config/win64-vc-config.py
+++ b/build_files/scons/config/win64-vc-config.py
@@ -190,7 +190,7 @@ CC = 'cl.exe'
CXX = 'cl.exe'
CFLAGS = []
-CCFLAGS = ['/nologo', '/Ob1', '/J', '/W0', '/Gd', '/we4013', '/wd4018', '/wd4244', '/wd4305', '/wd4800', '/wd4065', '/wd4267']
+CCFLAGS = ['/nologo', '/Ob1', '/J', '/W1', '/Gd', '/we4013', '/wd4018', '/wd4244', '/wd4305', '/wd4800', '/wd4065', '/wd4267']
CXXFLAGS = ['/EHsc']
BGE_CXXFLAGS = ['/O2', '/EHsc', '/GR', '/fp:fast']
diff --git a/doc/python_api/examples/bpy.types.Operator.4.py b/doc/python_api/examples/bpy.types.Operator.4.py
index 4cb7b02fdc6..861496c6d18 100644
--- a/doc/python_api/examples/bpy.types.Operator.4.py
+++ b/doc/python_api/examples/bpy.types.Operator.4.py
@@ -22,7 +22,7 @@ class CustomDrawOperator(bpy.types.Operator):
my_string = bpy.props.StringProperty(name="String Value")
def execute(self, context):
- print()
+ print("Test", self)
return {'FINISHED'}
def invoke(self, context, event):
diff --git a/doc/python_api/examples/bpy.types.Operator.5.py b/doc/python_api/examples/bpy.types.Operator.5.py
index 7d1a98d4c34..e123768431b 100644
--- a/doc/python_api/examples/bpy.types.Operator.5.py
+++ b/doc/python_api/examples/bpy.types.Operator.5.py
@@ -31,6 +31,7 @@ class ModalOperator(bpy.types.Operator):
def execute(self, context):
context.object.location.x = self.value / 100.0
+ return {'FINISHED'}
def modal(self, context, event):
if event.type == 'MOUSEMOVE': # Apply
diff --git a/doc/python_api/rst/info_best_practice.rst b/doc/python_api/rst/info_best_practice.rst
index f4daed9ad9f..16fd030b42a 100644
--- a/doc/python_api/rst/info_best_practice.rst
+++ b/doc/python_api/rst/info_best_practice.rst
@@ -2,9 +2,9 @@
Best Practice
*************
-When writing you're own scripts python is great for new developers to pick up and become productive, but you can also pick up odd habits or at least write scripts that are not easy for others to understand.
+When writing your own scripts python is great for new developers to pick up and become productive, but you can also pick up odd habits or at least write scripts that are not easy for others to understand.
-For you're own work this is of course fine, but if you want to collaborate with others or have you're work included with blender there are practices we encourage.
+For your own work this is of course fine, but if you want to collaborate with others or have your work included with blender there are practices we encourage.
Style Conventions
@@ -83,7 +83,7 @@ Even though you're not looping on the list data **python is**, so you need to be
Modifying Lists
^^^^^^^^^^^^^^^
-In python we can add and remove from a list, This is slower when the list length is modifier, especially at the start of the list, since all the data after the index of modification needs to be moved up or down 1 place.
+In python we can add and remove from a list, This is slower when the list length is modified, especially at the start of the list, since all the data after the index of modification needs to be moved up or down 1 place.
The most simple way to add onto the end of the list is to use ``my_list.append(list_item)`` or ``my_list.extend(some_list)`` and the fastest way to remove an item is ``my_list.pop()`` or ``del my_list[-1]``.
@@ -244,7 +244,7 @@ Use ``float(string)`` rather than ``eval(string)``, if you know the value will b
Checking String Start/End
^^^^^^^^^^^^^^^^^^^^^^^^^
-If your checking the start of a string for a keyword, rather than...
+If you're checking the start of a string for a keyword, rather than...
>>> if line[0:5] == "vert ": ...
@@ -279,8 +279,8 @@ Python has two ways to compare values ``a == b`` and ``a is b``, The difference
In cases where you know you are checking for the same value which is referenced from multiple places, ``is`` is faster.
-Time You're Code
-----------------
+Time Your Code
+--------------
While developing a script its good to time it to be aware of any changes in performance, this can be done simply.
diff --git a/doc/python_api/rst/info_quickstart.rst b/doc/python_api/rst/info_quickstart.rst
index be4ccdbcf72..c81d2ebe5ef 100644
--- a/doc/python_api/rst/info_quickstart.rst
+++ b/doc/python_api/rst/info_quickstart.rst
@@ -262,8 +262,7 @@ To run the script:
#. Click on the button **Run Script**.
-#. Move you're mouse into the 3D view, press spacebar for the operator search
- menu, and type "Simple".
+#. Move your mouse into the 3D view, press spacebar for the operator search menu, and type "Simple".
#. Click on the "Simple Operator" item found in search.
diff --git a/doc/python_api/rst/info_tips_and_tricks.rst b/doc/python_api/rst/info_tips_and_tricks.rst
index 5de7ded7674..491e97208dc 100644
--- a/doc/python_api/rst/info_tips_and_tricks.rst
+++ b/doc/python_api/rst/info_tips_and_tricks.rst
@@ -16,7 +16,7 @@ When writing python scripts, it's useful to have a terminal open, this is not th
There are 3 main uses for the terminal, these are:
-* You can see the output of ``print()`` as you're script runs, which is useful to view debug info.
+* You can see the output of ``print()`` as your script runs, which is useful to view debug info.
* The error trace-back is printed in full to the terminal which won't always generate an error popup in blender's user interface (depending on how the script is executed).
@@ -135,15 +135,15 @@ Once the script is running properly in background mode, you'll want to check the
* if the results can be displayed as text - print them or write them to a file.
-This can take a little time to setup, but it can be well worth the effort to reduce the time it takes to test changes - you can even have blender running the script ever few seconds with a viewer updating the results, so no need to leave you're text editor to see changes.
+This can take a little time to setup, but it can be well worth the effort to reduce the time it takes to test changes - you can even have blender running the script ever few seconds with a viewer updating the results, so no need to leave your text editor to see changes.
Use External Tools
==================
-When there are no readily available python modules to perform specific tasks it's worth keeping in mind you may be able to have python execute an external command on you're data and read the result back in.
+When there are no readily available python modules to perform specific tasks it's worth keeping in mind you may be able to have python execute an external command on your data and read the result back in.
-Using external programs adds an extra dependency and may limit who can use the script but to quickly setup you're own custom pipeline or writing one-off scripts this can be handy.
+Using external programs adds an extra dependency and may limit who can use the script but to quickly setup your own custom pipeline or writing one-off scripts this can be handy.
Examples include:
@@ -157,7 +157,7 @@ Examples include:
Bundled Python & Extensions
===========================
-The Blender releases distributed from blender.org include a complete python installation on all platforms, this has the disadvantage that any extensions you have installed in you're systems python wont be found by blender.
+The Blender releases distributed from blender.org include a complete python installation on all platforms, this has the disadvantage that any extensions you have installed in your systems python wont be found by blender.
There are 2 ways around this:
@@ -166,8 +166,8 @@ There are 2 ways around this:
* copy the extensions into blender's python sub-directory so blender can access them, you could also copy the entire python installation into blenders sub-directory, replacing the one blender comes with. This works as long as the python versions match and the paths are created in the same relative locations. Doing this has the advantage that you can redistribute this bundle to others with blender and/or the game player, including any extensions you rely on.
-Drop Into a Python Interpreter in You're Script
-===============================================
+Drop Into a Python Interpreter in Your Script
+=============================================
In the middle of a script you may want to inspect some variables, run some function and generally dig about to see whats going on.
@@ -187,7 +187,7 @@ If you want to access both global and local variables do this...
code.interact(local=namespace)
-The next example is an equivalent single line version of the script above which is easier to paste into you're code:
+The next example is an equivalent single line version of the script above which is easier to paste into your code:
.. code-block:: python
diff --git a/intern/cycles/app/cycles_server.cpp b/intern/cycles/app/cycles_server.cpp
index bcf4d3ea769..e6a13e04b48 100644
--- a/intern/cycles/app/cycles_server.cpp
+++ b/intern/cycles/app/cycles_server.cpp
@@ -34,8 +34,9 @@ int main(int argc, const char **argv)
/* device types */
string devices = "";
string devicename = "cpu";
+ bool list = false;
- vector<DeviceType> types = Device::available_types();
+ vector<DeviceType>& types = Device::available_types();
foreach(DeviceType type, types) {
if(devices != "")
@@ -49,6 +50,7 @@ int main(int argc, const char **argv)
ap.options ("Usage: cycles_server [options]",
"--device %s", &devicename, ("Devices to use: " + devices).c_str(),
+ "--list-devices", &list, "List information about all available devices",
NULL);
if(ap.parse(argc, argv) < 0) {
@@ -56,11 +58,34 @@ int main(int argc, const char **argv)
ap.usage();
exit(EXIT_FAILURE);
}
+ else if(list) {
+ vector<DeviceInfo>& devices = Device::available_devices();
- DeviceType dtype = Device::type_from_string(devicename.c_str());
+ printf("Devices:\n");
+
+ foreach(DeviceInfo& info, devices) {
+ printf(" %s%s\n",
+ info.description.c_str(),
+ (info.display_device)? " (display)": "");
+ }
+
+ exit(EXIT_SUCCESS);
+ }
+
+ /* find matching device */
+ DeviceType device_type = Device::type_from_string(devicename.c_str());
+ vector<DeviceInfo>& devices = Device::available_devices();
+ DeviceInfo device_info;
+
+ foreach(DeviceInfo& device, devices) {
+ if(device_type == device.type) {
+ device_info = device;
+ break;
+ }
+ }
while(1) {
- Device *device = Device::create(dtype);
+ Device *device = Device::create(device_info);
printf("Cycles Server with device: %s\n", device->description().c_str());
device->server_run();
delete device;
diff --git a/intern/cycles/app/cycles_test.cpp b/intern/cycles/app/cycles_test.cpp
index d9386f75141..0b8853d7036 100644
--- a/intern/cycles/app/cycles_test.cpp
+++ b/intern/cycles/app/cycles_test.cpp
@@ -203,17 +203,18 @@ static void options_parse(int argc, const char **argv)
options.session = NULL;
options.quiet = false;
- /* devices */
- string devices = "";
+ /* device names */
+ string device_names = "";
string devicename = "cpu";
+ bool list = false;
- vector<DeviceType> types = Device::available_types();
+ vector<DeviceType>& types = Device::available_types();
foreach(DeviceType type, types) {
- if(devices != "")
- devices += ", ";
+ if(device_names != "")
+ device_names += ", ";
- devices += Device::string_from_type(type);
+ device_names += Device::string_from_type(type);
}
/* shading system */
@@ -230,7 +231,7 @@ static void options_parse(int argc, const char **argv)
ap.options ("Usage: cycles_test [options] file.xml",
"%*", files_parse, "",
- "--device %s", &devicename, ("Devices to use: " + devices).c_str(),
+ "--device %s", &devicename, ("Devices to use: " + device_names).c_str(),
"--shadingsys %s", &ssname, "Shading system to use: svm, osl",
"--background", &options.session_params.background, "Render in background, without user interface",
"--quiet", &options.quiet, "In background mode, don't print progress messages",
@@ -239,6 +240,7 @@ static void options_parse(int argc, const char **argv)
"--threads %d", &options.session_params.threads, "CPU Rendering Threads",
"--width %d", &options.width, "Window width in pixel",
"--height %d", &options.height, "Window height in pixel",
+ "--list-devices", &list, "List information about all available devices",
"--help", &help, "Print help message",
NULL);
@@ -247,26 +249,44 @@ static void options_parse(int argc, const char **argv)
ap.usage();
exit(EXIT_FAILURE);
}
+ else if(list) {
+ vector<DeviceInfo>& devices = Device::available_devices();
+ printf("Devices:\n");
+
+ foreach(DeviceInfo& info, devices) {
+ printf(" %s%s\n",
+ info.description.c_str(),
+ (info.display_device)? " (display)": "");
+ }
+
+ exit(EXIT_SUCCESS);
+ }
else if(help || options.filepath == "") {
ap.usage();
exit(EXIT_SUCCESS);
}
- options.session_params.device_type = Device::type_from_string(devicename.c_str());
-
if(ssname == "osl")
options.scene_params.shadingsystem = SceneParams::OSL;
else if(ssname == "svm")
options.scene_params.shadingsystem = SceneParams::SVM;
- /* handle invalid configurations */
- bool type_available = false;
-
- foreach(DeviceType dtype, types)
- if(options.session_params.device_type == dtype)
- type_available = true;
+ /* find matching device */
+ DeviceType device_type = Device::type_from_string(devicename.c_str());
+ vector<DeviceInfo>& devices = Device::available_devices();
+ DeviceInfo device_info;
+ bool device_available = false;
+
+ foreach(DeviceInfo& device, devices) {
+ if(device_type == device.type) {
+ options.session_params.device = device;
+ device_available = true;
+ break;
+ }
+ }
- if(options.session_params.device_type == DEVICE_NONE || !type_available) {
+ /* handle invalid configurations */
+ if(options.session_params.device.type == DEVICE_NONE || !device_available) {
fprintf(stderr, "Unknown device: %s\n", devicename.c_str());
exit(EXIT_FAILURE);
}
@@ -278,7 +298,7 @@ static void options_parse(int argc, const char **argv)
fprintf(stderr, "Unknown shading system: %s\n", ssname.c_str());
exit(EXIT_FAILURE);
}
- else if(options.scene_params.shadingsystem == SceneParams::OSL && options.session_params.device_type != DEVICE_CPU) {
+ else if(options.scene_params.shadingsystem == SceneParams::OSL && options.session_params.device.type != DEVICE_CPU) {
fprintf(stderr, "OSL shading system only works with CPU device\n");
exit(EXIT_FAILURE);
}
diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp
index 72b8cfa2355..bc43809e46c 100644
--- a/intern/cycles/blender/blender_mesh.cpp
+++ b/intern/cycles/blender/blender_mesh.cpp
@@ -78,8 +78,9 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector<
for(b_mesh.faces.begin(f); f != b_mesh.faces.end(); ++f) {
int4 vi = get_int4(f->vertices_raw());
- int n= (vi[3] == 0)? 3: 4;
- int shader = used_shaders[f->material_index()];
+ int n = (vi[3] == 0)? 3: 4;
+ int mi = clamp(f->material_index(), 0, used_shaders.size()-1);
+ int shader = used_shaders[mi];
bool smooth = f->use_smooth();
mesh->add_triangle(vi[0], vi[1], vi[2], shader, smooth);
diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp
index 608c5fda5ac..caf5b0a99b1 100644
--- a/intern/cycles/blender/blender_object.cpp
+++ b/intern/cycles/blender/blender_object.cpp
@@ -234,13 +234,20 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d)
object_free_duplilist(*b_ob);
- /* check if we should render duplicator */
hide = true;
- BL::Object::particle_systems_iterator b_psys;
+ }
+
+ /* check if we should render or hide particle emitter */
+ BL::Object::particle_systems_iterator b_psys;
+ bool render_emitter = false;
- for(b_ob->particle_systems.begin(b_psys); b_psys != b_ob->particle_systems.end(); ++b_psys)
- if(b_psys->settings().use_render_emitter())
- hide = false;
+ for(b_ob->particle_systems.begin(b_psys); b_psys != b_ob->particle_systems.end(); ++b_psys) {
+ if(b_psys->settings().use_render_emitter()) {
+ hide = false;
+ render_emitter = true;
+ }
+ else if(!render_emitter)
+ hide = true;
}
if(!hide) {
diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp
index d8c65c7a607..2702327b67f 100644
--- a/intern/cycles/blender/blender_session.cpp
+++ b/intern/cycles/blender/blender_session.cpp
@@ -46,8 +46,8 @@ BlenderSession::BlenderSession(BL::RenderEngine b_engine_, BL::BlendData b_data_
/* offline render */
BL::RenderSettings r = b_scene.render();
- width = (int)(r.resolution_x()*r.resolution_percentage()*0.01f);
- height = (int)(r.resolution_y()*r.resolution_percentage()*0.01f);
+ width = (int)(r.resolution_x()*r.resolution_percentage()/100);
+ height = (int)(r.resolution_y()*r.resolution_percentage()/100);
background = true;
last_redraw_time = 0.0f;
diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp
index 3443f76b1ce..8f54f291cfb 100644
--- a/intern/cycles/blender/blender_sync.cpp
+++ b/intern/cycles/blender/blender_sync.cpp
@@ -69,13 +69,13 @@ bool BlenderSync::sync_recalc()
BL::BlendData::materials_iterator b_mat;
for(b_data.materials.begin(b_mat); b_mat != b_data.materials.end(); ++b_mat)
- if(b_mat->is_updated())
+ if(b_mat->is_updated() || (b_mat->node_tree() && b_mat->node_tree().is_updated()))
shader_map.set_recalc(*b_mat);
BL::BlendData::lamps_iterator b_lamp;
for(b_data.lamps.begin(b_lamp); b_lamp != b_data.lamps.end(); ++b_lamp)
- if(b_lamp->is_updated())
+ if(b_lamp->is_updated() || (b_lamp->node_tree() && b_lamp->node_tree().is_updated()))
shader_map.set_recalc(*b_lamp);
BL::BlendData::objects_iterator b_ob;
@@ -107,7 +107,8 @@ bool BlenderSync::sync_recalc()
BL::BlendData::worlds_iterator b_world;
for(b_data.worlds.begin(b_world); b_world != b_data.worlds.end(); ++b_world)
- if(world_map == b_world->ptr.data && b_world->is_updated())
+ if(world_map == b_world->ptr.data &&
+ (b_world->is_updated() || (b_world->node_tree() && b_world->node_tree().is_updated())))
world_recalc = true;
bool recalc =
@@ -247,10 +248,10 @@ bool BlenderSync::get_session_pause(BL::Scene b_scene, bool background)
return (background)? false: get_boolean(cscene, "preview_pause");
}
-static bool device_type_available(vector<DeviceType>& types, DeviceType dtype)
+static bool device_type_available(vector<DeviceInfo>& devices, DeviceType dtype)
{
- foreach(DeviceType dt, types)
- if(dt == dtype)
+ foreach(DeviceInfo& info, devices)
+ if(info.type == dtype)
return true;
return false;
@@ -265,24 +266,28 @@ SessionParams BlenderSync::get_session_params(BL::Scene b_scene, bool background
params.experimental = (RNA_enum_get(&cscene, "feature_set") != 0);
/* device type */
- params.device_type = DEVICE_CPU;
+ vector<DeviceInfo> devices = Device::available_devices();
+ DeviceType device_type = DEVICE_CPU;
if(RNA_enum_get(&cscene, "device") != 0) {
- vector<DeviceType> types = Device::available_types();
- DeviceType dtype;
if(!params.experimental || RNA_enum_get(&cscene, "gpu_type") == 0)
- dtype = DEVICE_CUDA;
+ device_type = DEVICE_CUDA;
else
- dtype = DEVICE_OPENCL;
-
- if(device_type_available(types, dtype))
- params.device_type = dtype;
- else if(params.experimental && device_type_available(types, DEVICE_OPENCL))
- params.device_type = DEVICE_OPENCL;
- else if(device_type_available(types, DEVICE_CUDA))
- params.device_type = DEVICE_CUDA;
+ device_type = DEVICE_OPENCL;
+
+ if(device_type_available(devices, device_type))
+ ;
+ else if(params.experimental && device_type_available(devices, DEVICE_OPENCL))
+ device_type = DEVICE_OPENCL;
+ else if(device_type_available(devices, DEVICE_CUDA))
+ device_type = DEVICE_CUDA;
}
+
+ params.device = devices[0];
+ foreach(DeviceInfo& info, devices)
+ if(info.type == device_type)
+ params.device = info;
/* Background */
params.background = background;
diff --git a/intern/cycles/device/device.cpp b/intern/cycles/device/device.cpp
index 55fc3bacbba..83600120fdd 100644
--- a/intern/cycles/device/device.cpp
+++ b/intern/cycles/device/device.cpp
@@ -118,7 +118,7 @@ void Device::pixels_free(device_memory& mem)
mem_free(mem);
}
-void Device::draw_pixels(device_memory& rgba, int y, int w, int h, int width, int height, bool transparent)
+void Device::draw_pixels(device_memory& rgba, int y, int w, int h, int dy, int width, int height, bool transparent)
{
pixels_copy_from(rgba, y, w, h);
@@ -128,7 +128,7 @@ void Device::draw_pixels(device_memory& rgba, int y, int w, int h, int width, in
}
glPixelZoom((float)width/(float)w, (float)height/(float)h);
- glRasterPos2f(0, y);
+ glRasterPos2f(0, dy);
uint8_t *pixels = (uint8_t*)rgba.data_pointer;
@@ -145,36 +145,36 @@ void Device::draw_pixels(device_memory& rgba, int y, int w, int h, int width, in
glDisable(GL_BLEND);
}
-Device *Device::create(DeviceType type, bool background, int threads)
+Device *Device::create(DeviceInfo& info, bool background, int threads)
{
Device *device;
- switch(type) {
+ switch(info.type) {
case DEVICE_CPU:
- device = device_cpu_create(threads);
+ device = device_cpu_create(info, threads);
break;
#ifdef WITH_CUDA
case DEVICE_CUDA:
if(cuLibraryInit())
- device = device_cuda_create(background);
+ device = device_cuda_create(info, background);
else
device = NULL;
break;
#endif
#ifdef WITH_MULTI
case DEVICE_MULTI:
- device = device_multi_create(background);
+ device = device_multi_create(info, background);
break;
#endif
#ifdef WITH_NETWORK
case DEVICE_NETWORK:
- device = device_network_create("127.0.0.1");
+ device = device_network_create(info, "127.0.0.1");
break;
#endif
#ifdef WITH_OPENCL
case DEVICE_OPENCL:
if(clLibraryInit())
- device = device_opencl_create(background);
+ device = device_opencl_create(info, background);
else
device = NULL;
break;
@@ -218,31 +218,68 @@ string Device::string_from_type(DeviceType type)
return "";
}
-vector<DeviceType> Device::available_types()
+vector<DeviceType>& Device::available_types()
{
- vector<DeviceType> types;
+ static vector<DeviceType> types;
+ static bool types_init = false;
- types.push_back(DEVICE_CPU);
+ if(!types_init) {
+ types.push_back(DEVICE_CPU);
#ifdef WITH_CUDA
- if(cuLibraryInit())
- types.push_back(DEVICE_CUDA);
+ if(cuLibraryInit())
+ types.push_back(DEVICE_CUDA);
#endif
#ifdef WITH_OPENCL
- if(clLibraryInit())
- types.push_back(DEVICE_OPENCL);
+ if(clLibraryInit())
+ types.push_back(DEVICE_OPENCL);
#endif
#ifdef WITH_NETWORK
- types.push_back(DEVICE_NETWORK);
+ types.push_back(DEVICE_NETWORK);
#endif
#ifdef WITH_MULTI
- types.push_back(DEVICE_MULTI);
+ types.push_back(DEVICE_MULTI);
#endif
+ types_init = true;
+ }
+
return types;
}
+vector<DeviceInfo>& Device::available_devices()
+{
+ static vector<DeviceInfo> devices;
+ static bool devices_init = false;
+
+ if(!devices_init) {
+ device_cpu_info(devices);
+
+#ifdef WITH_CUDA
+ if(cuLibraryInit())
+ device_cuda_info(devices);
+#endif
+
+#ifdef WITH_OPENCL
+ if(clLibraryInit())
+ device_opencl_info(devices);
+#endif
+
+#ifdef WITH_MULTI
+ device_multi_info(devices);
+#endif
+
+#ifdef WITH_NETWORK
+ device_network_info(devices);
+#endif
+
+ devices_init = true;
+ }
+
+ return devices;
+}
+
CCL_NAMESPACE_END
diff --git a/intern/cycles/device/device.h b/intern/cycles/device/device.h
index af9bb694c1b..51505aa9cb9 100644
--- a/intern/cycles/device/device.h
+++ b/intern/cycles/device/device.h
@@ -33,6 +33,8 @@ CCL_NAMESPACE_BEGIN
class Progress;
+/* Device Types */
+
enum DeviceType {
DEVICE_NONE,
DEVICE_CPU,
@@ -42,10 +44,22 @@ enum DeviceType {
DEVICE_MULTI
};
-enum MemoryType {
- MEM_READ_ONLY,
- MEM_WRITE_ONLY,
- MEM_READ_WRITE
+class DeviceInfo {
+public:
+ DeviceType type;
+ string description;
+ string id;
+ int num;
+ bool display_device;
+ vector<DeviceInfo> multi_devices;
+
+ DeviceInfo()
+ {
+ type = DEVICE_CPU;
+ id = "CPU";
+ num = 0;
+ display_device = false;
+ }
};
/* Device Task */
@@ -91,7 +105,7 @@ public:
/* info */
virtual string description() = 0;
- const string& error_message() { return error_msg; }
+ virtual const string& error_message() { return error_msg; }
/* regular memory */
virtual void mem_alloc(device_memory& mem, MemoryType type) = 0;
@@ -127,7 +141,7 @@ public:
/* opengl drawing */
virtual void draw_pixels(device_memory& mem, int y, int w, int h,
- int width, int height, bool transparent);
+ int dy, int width, int height, bool transparent);
#ifdef WITH_NETWORK
/* networking */
@@ -135,11 +149,12 @@ public:
#endif
/* static */
- static Device *create(DeviceType type, bool background = true, int threads = 0);
+ static Device *create(DeviceInfo& info, bool background = true, int threads = 0);
static DeviceType type_from_string(const char *name);
static string string_from_type(DeviceType type);
- static vector<DeviceType> available_types();
+ static vector<DeviceType>& available_types();
+ static vector<DeviceInfo>& available_devices();
};
CCL_NAMESPACE_END
diff --git a/intern/cycles/device/device_cpu.cpp b/intern/cycles/device/device_cpu.cpp
index 145eab9ff59..c93c6ff17da 100644
--- a/intern/cycles/device/device_cpu.cpp
+++ b/intern/cycles/device/device_cpu.cpp
@@ -258,10 +258,22 @@ public:
}
};
-Device *device_cpu_create(int threads)
+Device *device_cpu_create(DeviceInfo& info, int threads)
{
return new CPUDevice(threads);
}
+void device_cpu_info(vector<DeviceInfo>& devices)
+{
+ DeviceInfo info;
+
+ info.type = DEVICE_CPU;
+ info.description = system_cpu_brand_string();
+ info.id = "CPU";
+ info.num = 0;
+
+ devices.push_back(info);
+}
+
CCL_NAMESPACE_END
diff --git a/intern/cycles/device/device_cuda.cpp b/intern/cycles/device/device_cuda.cpp
index 3c5aafd3f60..73d87ae4a2e 100644
--- a/intern/cycles/device/device_cuda.cpp
+++ b/intern/cycles/device/device_cuda.cpp
@@ -159,11 +159,11 @@ public:
cuda_assert(cuCtxSetCurrent(NULL));
}
- CUDADevice(bool background_)
+ CUDADevice(DeviceInfo& info, bool background_)
{
background = background_;
- cuDevId = 0;
+ cuDevId = info.num;
cuDevice = 0;
cuContext = 0;
@@ -205,7 +205,7 @@ public:
string description()
{
/* print device information */
- char deviceName[100];
+ char deviceName[256];
cuda_push_context();
cuDeviceGetName(deviceName, 256, cuDevId);
@@ -768,7 +768,7 @@ public:
}
}
- void draw_pixels(device_memory& mem, int y, int w, int h, int width, int height, bool transparent)
+ void draw_pixels(device_memory& mem, int y, int w, int h, int dy, int width, int height, bool transparent)
{
if(!background) {
PixelMem pmem = pixel_mem_map[mem.device_pointer];
@@ -794,7 +794,7 @@ public:
glColor3f(1.0f, 1.0f, 1.0f);
glPushMatrix();
- glTranslatef(0.0f, (float)y, 0.0f);
+ glTranslatef(0.0f, (float)dy, 0.0f);
glBegin(GL_QUADS);
@@ -822,7 +822,7 @@ public:
return;
}
- Device::draw_pixels(mem, y, w, h, width, height, transparent);
+ Device::draw_pixels(mem, y, w, h, dy, width, height, transparent);
}
void task_add(DeviceTask& task)
@@ -849,9 +849,40 @@ public:
}
};
-Device *device_cuda_create(bool background)
+Device *device_cuda_create(DeviceInfo& info, bool background)
{
- return new CUDADevice(background);
+ return new CUDADevice(info, background);
+}
+
+void device_cuda_info(vector<DeviceInfo>& devices)
+{
+ int count = 0;
+
+ if(cuInit(0) != CUDA_SUCCESS)
+ return;
+ if(cuDeviceGetCount(&count) != CUDA_SUCCESS)
+ return;
+
+ for(int num = 0; num < count; num++) {
+ char name[256];
+ int attr;
+
+ if(cuDeviceGetName(name, 256, num) != CUDA_SUCCESS)
+ continue;
+
+ DeviceInfo info;
+
+ info.type = DEVICE_CUDA;
+ info.description = string(name);
+ info.id = string_printf("CUDA_%d", num);
+ info.num = num;
+
+ /* 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.display_device = true;
+
+ devices.push_back(info);
+ }
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/device/device_intern.h b/intern/cycles/device/device_intern.h
index e098ac1f0e3..e3601aa8ad4 100644
--- a/intern/cycles/device/device_intern.h
+++ b/intern/cycles/device/device_intern.h
@@ -23,11 +23,17 @@ CCL_NAMESPACE_BEGIN
class Device;
-Device *device_cpu_create(int threads);
-Device *device_opencl_create(bool background);
-Device *device_cuda_create(bool background);
-Device *device_network_create(const char *address);
-Device *device_multi_create(bool background);
+Device *device_cpu_create(DeviceInfo& info, int threads);
+Device *device_opencl_create(DeviceInfo& info, bool background);
+Device *device_cuda_create(DeviceInfo& info, bool background);
+Device *device_network_create(DeviceInfo& info, const char *address);
+Device *device_multi_create(DeviceInfo& info, bool background);
+
+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);
CCL_NAMESPACE_END
diff --git a/intern/cycles/device/device_memory.h b/intern/cycles/device/device_memory.h
index 516a6bd0739..3223ca91b9e 100644
--- a/intern/cycles/device/device_memory.h
+++ b/intern/cycles/device/device_memory.h
@@ -36,6 +36,12 @@
CCL_NAMESPACE_BEGIN
+enum MemoryType {
+ MEM_READ_ONLY,
+ MEM_WRITE_ONLY,
+ MEM_READ_WRITE
+};
+
/* Supported Data Types */
enum DataType {
diff --git a/intern/cycles/device/device_multi.cpp b/intern/cycles/device/device_multi.cpp
index 7f24e5789cc..f8b512f209c 100644
--- a/intern/cycles/device/device_multi.cpp
+++ b/intern/cycles/device/device_multi.cpp
@@ -44,32 +44,18 @@ public:
list<SubDevice> devices;
device_ptr unique_ptr;
- MultiDevice(bool background_)
+ MultiDevice(DeviceInfo& info, bool background_)
: unique_ptr(1)
{
Device *device;
+ background = background_;
- /* add CPU device */
- device = Device::create(DEVICE_CPU, background);
- devices.push_back(SubDevice(device));
-
-#ifdef WITH_CUDA
- /* try to add GPU device */
- device = Device::create(DEVICE_CUDA, background);
- if(device) {
+ foreach(DeviceInfo& subinfo, info.multi_devices) {
+ device = Device::create(subinfo, background);
devices.push_back(SubDevice(device));
}
- else
-#endif
- {
-#ifdef WITH_OPENCL
- device = Device::create(DEVICE_OPENCL, background);
- if(device)
- devices.push_back(SubDevice(device));
-#endif
- }
-#ifdef WITH_NETWORK
+#if 0 //def WITH_NETWORK
/* try to add network devices */
ServerDiscovery discovery(true);
time_sleep(1.0);
@@ -77,7 +63,7 @@ public:
list<string> servers = discovery.get_server_list();
foreach(string& server, servers) {
- device = device_network_create(server.c_str());
+ device = device_network_create(info, server.c_str());
if(device)
devices.push_back(SubDevice(device));
}
@@ -100,6 +86,19 @@ public:
return true;
}
+ const string& error_message()
+ {
+ foreach(SubDevice& sub, devices) {
+ if(sub.device->error_message() != "") {
+ if(error_msg == "")
+ error_msg = sub.device->error_message();
+ break;
+ }
+ }
+
+ return error_msg;
+ }
+
string description()
{
/* create map to find duplicate descriptions */
@@ -274,7 +273,7 @@ public:
mem.device_pointer = tmp;
}
- void draw_pixels(device_memory& rgba, int y, int w, int h, int width, int height, bool transparent)
+ void draw_pixels(device_memory& rgba, int y, int w, int h, int dy, int width, int height, bool transparent)
{
device_ptr tmp = rgba.device_pointer;
int i = 0, sub_h = h/devices.size();
@@ -284,10 +283,11 @@ public:
int sy = y + i*sub_h;
int sh = (i == (int)devices.size() - 1)? h - sub_h*i: sub_h;
int sheight = (i == (int)devices.size() - 1)? height - sub_height*i: sub_height;
+ int sdy = dy + i*sub_height;
/* adjust math for w/width */
rgba.device_pointer = sub.ptr_map[tmp];
- sub.device->draw_pixels(rgba, sy, w, sh, width, sheight, transparent);
+ sub.device->draw_pixels(rgba, sy, w, sh, sdy, width, sheight, transparent);
i++;
}
@@ -327,9 +327,103 @@ public:
}
};
-Device *device_multi_create(bool background)
+Device *device_multi_create(DeviceInfo& info, bool background)
+{
+ return new MultiDevice(info, background);
+}
+
+static void device_multi_add(vector<DeviceInfo>& devices, DeviceType type, bool skip_display, const char *id_fmt, int num)
{
- return new MultiDevice(background);
+ DeviceInfo info;
+
+ /* create map to find duplicate descriptions */
+ map<string, int> dupli_map;
+ map<string, int>::iterator dt;
+ int num_added = 0, num_skipped = 0;
+
+ foreach(DeviceInfo& subinfo, devices) {
+ if(subinfo.type == type) {
+ if(skip_display && subinfo.display_device) {
+ num_skipped++;
+ }
+ else {
+ 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;
+ num_added++;
+ }
+ }
+ }
+
+ if(num_added <= 1 || (skip_display && num_skipped == 0))
+ return;
+
+ /* 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.num = 0;
+
+ devices.push_back(info);
+}
+
+void device_multi_info(vector<DeviceInfo>& devices)
+{
+ int num = 0;
+ device_multi_add(devices, DEVICE_CUDA, true, "CUDA_MULTI_%d", num++);
+ device_multi_add(devices, DEVICE_CUDA, false, "CUDA_MULTI_%d", num++);
+
+ num = 0;
+ device_multi_add(devices, DEVICE_OPENCL, true, "OPENCL_MULTI_%d", num++);
+ device_multi_add(devices, DEVICE_OPENCL, false, "OPENCL_MULTI_%d", num++);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/device/device_network.cpp b/intern/cycles/device/device_network.cpp
index a5ad84831fc..4347d7eecd8 100644
--- a/intern/cycles/device/device_network.cpp
+++ b/intern/cycles/device/device_network.cpp
@@ -220,11 +220,22 @@ public:
}
};
-Device *device_network_create(const char *address)
+Device *device_network_create(DeviceInfo& info, const char *address)
{
return new NetworkDevice(address);
}
+void device_network_info(vector<DeviceInfo>& devices)
+{
+ DeviceInfo info;
+
+ info.type = DEVICE_NETWORK;
+ info.description = "Network Device";
+ info.id = "NETWORK";
+ info.num = 0;
+
+ devices.push_back(info);
+}
void Device::server_run()
{
diff --git a/intern/cycles/device/device_opencl.cpp b/intern/cycles/device/device_opencl.cpp
index 6014dd0fdb7..41844d37f50 100644
--- a/intern/cycles/device/device_opencl.cpp
+++ b/intern/cycles/device/device_opencl.cpp
@@ -141,7 +141,7 @@ public:
}
}
- OpenCLDevice(bool background_)
+ OpenCLDevice(DeviceInfo& info, bool background_)
{
background = background_;
cpPlatform = NULL;
@@ -153,10 +153,9 @@ public:
null_mem = 0;
device_initialized = false;
- vector<cl_platform_id> platform_ids;
+ /* setup platform */
cl_uint num_platforms;
- /* setup device */
ciErr = clGetPlatformIDs(0, NULL, &num_platforms);
if(opencl_error(ciErr))
return;
@@ -166,14 +165,7 @@ public:
return;
}
- platform_ids.resize(num_platforms);
- ciErr = clGetPlatformIDs(num_platforms, &platform_ids[0], NULL);
- if(opencl_error(ciErr))
- return;
-
- cpPlatform = platform_ids[0]; /* todo: pick specified platform && device */
-
- ciErr = clGetDeviceIDs(cpPlatform, CL_DEVICE_TYPE_GPU|CL_DEVICE_TYPE_ACCELERATOR, 1, &cdDevice, NULL);
+ ciErr = clGetPlatformIDs(num_platforms, &cpPlatform, NULL);
if(opencl_error(ciErr))
return;
@@ -181,6 +173,29 @@ public:
clGetPlatformInfo(cpPlatform, CL_PLATFORM_NAME, sizeof(name), &name, NULL);
platform_name = name;
+ /* get devices */
+ vector<cl_device_id> device_ids;
+ cl_uint num_devices;
+
+ if(opencl_error(clGetDeviceIDs(cpPlatform, CL_DEVICE_TYPE_GPU|CL_DEVICE_TYPE_ACCELERATOR, 0, NULL, &num_devices)))
+ return;
+
+ if(info.num > num_devices) {
+ if(num_devices == 0)
+ opencl_error("OpenCL: no devices found.");
+ else
+ opencl_error("OpenCL: specified device not found.");
+ return;
+ }
+
+ device_ids.resize(num_devices);
+
+ if(opencl_error(clGetDeviceIDs(cpPlatform, CL_DEVICE_TYPE_GPU|CL_DEVICE_TYPE_ACCELERATOR, num_devices, &device_ids[0], NULL)))
+ return;
+
+ cdDevice = device_ids[info.num];
+
+ /* create context */
cxContext = clCreateContext(0, 1, &cdDevice, NULL, NULL, &ciErr);
if(opencl_error(ciErr))
return;
@@ -689,9 +704,50 @@ public:
}
};
-Device *device_opencl_create(bool background)
+Device *device_opencl_create(DeviceInfo& info, bool background)
{
- return new OpenCLDevice(background);
+ return new OpenCLDevice(info, background);
+}
+
+void device_opencl_info(vector<DeviceInfo>& devices)
+{
+ vector<cl_device_id> device_ids;
+ cl_uint num_devices;
+ cl_platform_id platform_id;
+ cl_uint num_platforms;
+
+ /* get devices */
+ if(clGetPlatformIDs(0, NULL, &num_platforms) != CL_SUCCESS || num_platforms == 0)
+ return;
+
+ if(clGetPlatformIDs(num_platforms, &platform_id, NULL) != CL_SUCCESS)
+ return;
+
+ if(clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_GPU|CL_DEVICE_TYPE_ACCELERATOR, 0, NULL, &num_devices) != CL_SUCCESS)
+ return;
+
+ device_ids.resize(num_devices);
+
+ if(clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_GPU|CL_DEVICE_TYPE_ACCELERATOR, num_devices, &device_ids[0], NULL) != CL_SUCCESS)
+ return;
+
+ /* add devices */
+ for(int num = 0; num < num_devices; num++) {
+ cl_device_id device_id = device_ids[num];
+ char name[1024];
+
+ if(clGetDeviceInfo(device_id, CL_DEVICE_NAME, sizeof(name), &name, NULL) != CL_SUCCESS)
+ continue;
+
+ DeviceInfo info;
+
+ info.type = DEVICE_OPENCL;
+ info.description = string(name);
+ info.id = string_printf("OPENCL_%d", num);
+ info.num = num;
+
+ devices.push_back(info);
+ }
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/buffers.cpp b/intern/cycles/render/buffers.cpp
index 29141b25b59..dd78ccd8f32 100644
--- a/intern/cycles/render/buffers.cpp
+++ b/intern/cycles/render/buffers.cpp
@@ -183,7 +183,7 @@ void DisplayBuffer::draw(Device *device)
if(transparent)
draw_transparency_grid();
- device->draw_pixels(rgba, 0, draw_width, draw_height, params.width, params.height, transparent);
+ device->draw_pixels(rgba, 0, draw_width, draw_height, 0, params.width, params.height, transparent);
}
}
diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp
index be2e493dc7f..4634e4de0d8 100644
--- a/intern/cycles/render/session.cpp
+++ b/intern/cycles/render/session.cpp
@@ -35,9 +35,9 @@ Session::Session(const SessionParams& params_)
: params(params_),
tile_manager(params.progressive, params.samples, params.tile_size, params.min_size)
{
- device_use_gl = ((params.device_type != DEVICE_CPU) && !params.background);
+ device_use_gl = ((params.device.type != DEVICE_CPU) && !params.background);
- device = Device::create(params.device_type, params.background, params.threads);
+ device = Device::create(params.device, params.background, params.threads);
buffers = new RenderBuffers(device);
display = new DisplayBuffer(device);
diff --git a/intern/cycles/render/session.h b/intern/cycles/render/session.h
index 89979b8c451..a662948c15b 100644
--- a/intern/cycles/render/session.h
+++ b/intern/cycles/render/session.h
@@ -40,7 +40,7 @@ class Scene;
class SessionParams {
public:
- DeviceType device_type;
+ DeviceInfo device;
bool background;
string output_path;
@@ -57,7 +57,6 @@ public:
SessionParams()
{
- device_type = DEVICE_CPU;
background = false;
output_path = "";
@@ -74,7 +73,8 @@ public:
}
bool modified(const SessionParams& params)
- { return !(device_type == params.device_type
+ { return !(device.type == params.device.type
+ && device.id == params.device.id
&& background == params.background
&& output_path == params.output_path
/* && samples == params.samples */
diff --git a/intern/cycles/render/tile.cpp b/intern/cycles/render/tile.cpp
index 40833e5b08b..04e48d44029 100644
--- a/intern/cycles/render/tile.cpp
+++ b/intern/cycles/render/tile.cpp
@@ -71,8 +71,8 @@ void TileManager::set_tiles()
int resolution = state.resolution;
int image_w = max(1, params.width/resolution);
int image_h = max(1, params.height/resolution);
- int tile_w = (image_w + tile_size - 1)/tile_size;
- int tile_h = (image_h + tile_size - 1)/tile_size;
+ int tile_w = (tile_size >= image_w)? 1: (image_w + tile_size - 1)/tile_size;
+ int tile_h = (tile_size >= image_h)? 1: (image_h + tile_size - 1)/tile_size;
int sub_w = image_w/tile_w;
int sub_h = image_h/tile_h;
diff --git a/intern/ghost/CMakeLists.txt b/intern/ghost/CMakeLists.txt
index a84ff5825a9..35b617e5452 100644
--- a/intern/ghost/CMakeLists.txt
+++ b/intern/ghost/CMakeLists.txt
@@ -234,6 +234,13 @@ elseif(UNIX)
)
endif()
+ if(WITH_X11_XF86VMODE)
+ add_definitions(-DWITH_X11_XF86VMODE)
+ list(APPEND INC_SYS
+ ${X11_xf86vmode_INCLUDE_PATH}
+ )
+ endif()
+
if(WITH_INPUT_NDOF)
list(APPEND SRC
intern/GHOST_NDOFManagerX11.cpp
diff --git a/intern/ghost/intern/GHOST_DisplayManagerSDL.cpp b/intern/ghost/intern/GHOST_DisplayManagerSDL.cpp
index 1b73329f8bb..4c67616a4c4 100644
--- a/intern/ghost/intern/GHOST_DisplayManagerSDL.cpp
+++ b/intern/ghost/intern/GHOST_DisplayManagerSDL.cpp
@@ -36,7 +36,7 @@ GHOST_DisplayManagerSDL::GHOST_DisplayManagerSDL(GHOST_SystemSDL *system)
}
GHOST_TSuccess
-GHOST_DisplayManagerSDL::getNumDisplays(GHOST_TUns8& numDisplays)
+GHOST_DisplayManagerSDL::getNumDisplays(GHOST_TUns8& numDisplays) const
{
numDisplays= SDL_GetNumVideoDisplays();
return GHOST_kSuccess;
@@ -44,7 +44,7 @@ GHOST_DisplayManagerSDL::getNumDisplays(GHOST_TUns8& numDisplays)
GHOST_TSuccess GHOST_DisplayManagerSDL::getNumDisplaySettings(GHOST_TUns8 display,
- GHOST_TInt32& numSettings)
+ GHOST_TInt32& numSettings) const
{
GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n");
numSettings= GHOST_TInt32(1);
@@ -54,7 +54,7 @@ GHOST_TSuccess GHOST_DisplayManagerSDL::getNumDisplaySettings(GHOST_TUns8 displa
GHOST_TSuccess
GHOST_DisplayManagerSDL::getDisplaySetting(GHOST_TUns8 display,
GHOST_TInt32 index,
- GHOST_DisplaySetting& setting)
+ GHOST_DisplaySetting& setting) const
{
GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n");
@@ -74,7 +74,7 @@ GHOST_DisplayManagerSDL::getDisplaySetting(GHOST_TUns8 display,
GHOST_TSuccess
GHOST_DisplayManagerSDL::getCurrentDisplaySetting(GHOST_TUns8 display,
- GHOST_DisplaySetting& setting)
+ GHOST_DisplaySetting& setting) const
{
return getDisplaySetting(display,GHOST_TInt32(0),setting);
}
diff --git a/intern/ghost/intern/GHOST_DisplayManagerSDL.h b/intern/ghost/intern/GHOST_DisplayManagerSDL.h
index ff8ab13c4fa..297a61f41ff 100644
--- a/intern/ghost/intern/GHOST_DisplayManagerSDL.h
+++ b/intern/ghost/intern/GHOST_DisplayManagerSDL.h
@@ -46,20 +46,20 @@ public:
GHOST_DisplayManagerSDL(GHOST_SystemSDL *system);
GHOST_TSuccess
- getNumDisplays(GHOST_TUns8& numDisplays);
+ getNumDisplays(GHOST_TUns8& numDisplays) const;
GHOST_TSuccess
getNumDisplaySettings(GHOST_TUns8 display,
- GHOST_TInt32& numSettings);
+ GHOST_TInt32& numSettings) const;
GHOST_TSuccess
getDisplaySetting(GHOST_TUns8 display,
GHOST_TInt32 index,
- GHOST_DisplaySetting& setting);
+ GHOST_DisplaySetting& setting) const;
GHOST_TSuccess
getCurrentDisplaySetting(GHOST_TUns8 display,
- GHOST_DisplaySetting& setting);
+ GHOST_DisplaySetting& setting) const;
GHOST_TSuccess
setCurrentDisplaySetting(GHOST_TUns8 display,
diff --git a/intern/ghost/intern/GHOST_DisplayManagerX11.cpp b/intern/ghost/intern/GHOST_DisplayManagerX11.cpp
index 34f5fda2a16..411203b6475 100644
--- a/intern/ghost/intern/GHOST_DisplayManagerX11.cpp
+++ b/intern/ghost/intern/GHOST_DisplayManagerX11.cpp
@@ -20,7 +20,9 @@
*
* The Original Code is: all of this file.
*
- * Contributor(s): none yet.
+ * Video mode switching
+ * Copyright (C) 1997-2001 Id Software, Inc.
+ * Ported from Quake 2 by Alex Fraser <alex@phatcore.com>
*
* ***** END GPL LICENSE BLOCK *****
*/
@@ -29,6 +31,10 @@
* \ingroup GHOST
*/
+#ifdef WITH_X11_XF86VMODE
+# include <X11/Xlib.h>
+# include <X11/extensions/xf86vmode.h>
+#endif
#include "GHOST_DisplayManagerX11.h"
#include "GHOST_SystemX11.h"
@@ -112,12 +118,74 @@ setCurrentDisplaySetting(
GHOST_TUns8 display,
const GHOST_DisplaySetting& setting
){
- // This is never going to work robustly in X
- // but it's currently part of the full screen interface
+#ifdef WITH_X11_XF86VMODE
+ //
+ // Mode switching code ported from Quake 2:
+ // ftp://ftp.idsoftware.com/idstuff/source/q2source-3.21.zip
+ // See linux/gl_glx.c:GLimp_SetMode
+ //
+ int majorVersion, minorVersion;
+ XF86VidModeModeInfo **vidmodes;
+ Display *dpy = m_system->getXDisplay();
+ int scrnum, num_vidmodes;
+ int best_fit, best_dist, dist, x, y;
+
+ scrnum = DefaultScreen(dpy);
+
+ // Get video mode list
+ majorVersion = minorVersion = 0;
+ if (!XF86VidModeQueryVersion(dpy, &majorVersion, &minorVersion)) {
+ fprintf(stderr, "Error: XF86VidMode extension missing!\n");
+ return GHOST_kFailure;
+ }
+# ifdef _DEBUG
+ printf("Using XFree86-VidModeExtension Version %d.%d\n",
+ majorVersion, minorVersion);
+# endif
+
+ XF86VidModeGetAllModeLines(dpy, scrnum, &num_vidmodes, &vidmodes);
+
+ best_dist = 9999999;
+ best_fit = -1;
+
+ for (int i = 0; i < num_vidmodes; i++) {
+ if (setting.xPixels > vidmodes[i]->hdisplay ||
+ setting.yPixels > vidmodes[i]->vdisplay)
+ continue;
+
+ x = setting.xPixels - vidmodes[i]->hdisplay;
+ y = setting.yPixels - vidmodes[i]->vdisplay;
+ dist = (x * x) + (y * y);
+ if (dist < best_dist) {
+ best_dist = dist;
+ best_fit = i;
+ }
+ }
- // we fudge it for now.
+ if (best_fit != -1) {
+# ifdef _DEBUG
+ int actualWidth, actualHeight;
+ actualWidth = vidmodes[best_fit]->hdisplay;
+ actualHeight = vidmodes[best_fit]->vdisplay;
+ printf("Switching to video mode %dx%d\n",
+ actualWidth, actualHeight);
+# endif
+
+ // change to the mode
+ XF86VidModeSwitchToMode(dpy, scrnum, vidmodes[best_fit]);
+
+ // Move the viewport to top left
+ XF86VidModeSetViewPort(dpy, scrnum, 0, 0);
+ } else
+ return GHOST_kFailure;
+
+ XFlush(dpy);
+ return GHOST_kSuccess;
+#else
+ // Just pretend the request was successful.
return GHOST_kSuccess;
+#endif
}
diff --git a/release/scripts/modules/animsys_refactor.py b/release/scripts/modules/animsys_refactor.py
index f97ba3c2a50..8db21e357d9 100644
--- a/release/scripts/modules/animsys_refactor.py
+++ b/release/scripts/modules/animsys_refactor.py
@@ -38,6 +38,7 @@ class DataPathBuilder(object):
""" Dummy class used to parse fcurve and driver data paths.
"""
__slots__ = ("data_path", )
+
def __init__(self, attrs):
self.data_path = attrs
diff --git a/release/scripts/modules/rna_prop_ui.py b/release/scripts/modules/rna_prop_ui.py
index 388ae2b0e13..32c8ed11bc5 100644
--- a/release/scripts/modules/rna_prop_ui.py
+++ b/release/scripts/modules/rna_prop_ui.py
@@ -145,11 +145,11 @@ def draw(layout, context, context_member, property_type, use_edit=True):
if use_edit:
row = split.row(align=True)
- prop = row.operator("wm.properties_edit", text="edit")
- assign_props(prop, val_draw, key)
+ props = row.operator("wm.properties_edit", text="edit")
+ assign_props(props, val_draw, key)
- prop = row.operator("wm.properties_remove", text="", icon='ZOOMOUT')
- assign_props(prop, val_draw, key)
+ props = row.operator("wm.properties_remove", text="", icon='ZOOMOUT')
+ assign_props(props, val_draw, key)
class PropertyPanel():
diff --git a/release/scripts/modules/rna_xml.py b/release/scripts/modules/rna_xml.py
new file mode 100644
index 00000000000..1a0cf4bab9d
--- /dev/null
+++ b/release/scripts/modules/rna_xml.py
@@ -0,0 +1,300 @@
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# Contributor(s): Campbell Barton
+#
+# ***** END GPL LICENSE BLOCK *****
+
+# <pep8 compliant>
+
+import bpy
+
+
+def build_property_typemap(skip_classes):
+
+ property_typemap = {}
+
+ for attr in dir(bpy.types):
+ cls = getattr(bpy.types, attr)
+ if issubclass(cls, skip_classes):
+ continue
+
+ properties = cls.bl_rna.properties.keys()
+ properties.remove("rna_type")
+ property_typemap[attr] = properties
+
+ return property_typemap
+
+
+def print_ln(data):
+ print(data, end="")
+
+
+def rna2xml(fw=print_ln,
+ root_node="",
+ root_rna=None, # must be set
+ root_rna_skip=set(),
+ ident_val=" ",
+ skip_classes=(bpy.types.Operator,
+ bpy.types.Panel,
+ bpy.types.KeyingSet,
+ bpy.types.Header,
+ ),
+ pretty_format=True,
+ method='DATA'):
+
+ from xml.sax.saxutils import quoteattr
+ property_typemap = build_property_typemap(skip_classes)
+
+ def number_to_str(val, val_type):
+ if val_type == int:
+ return "%d" % val
+ elif val_type == float:
+ return "%.6g" % val
+ elif val_type == bool:
+ return "TRUE" if val else "FALSE"
+ else:
+ raise NotImplemented("this type is not a number %s" % val_type)
+
+ def rna2xml_node(ident, value, parent):
+ ident_next = ident + ident_val
+
+ # divide into attrs and nodes.
+ node_attrs = []
+ nodes_items = []
+ nodes_lists = []
+
+ value_type = type(value)
+
+ if issubclass(value_type, skip_classes):
+ return
+
+ # XXX, fixme, pointcache has eternal nested pointer to its self.
+ if value == parent:
+ return
+
+ value_type_name = value_type.__name__
+ for prop in property_typemap[value_type_name]:
+
+ subvalue = getattr(value, prop)
+ subvalue_type = type(subvalue)
+
+ if subvalue_type in (int, bool, float):
+ node_attrs.append("%s=\"%s\"" % (prop, number_to_str(subvalue, subvalue_type)))
+ elif subvalue_type is str:
+ node_attrs.append("%s=%s" % (prop, quoteattr(subvalue)))
+ elif subvalue_type == set:
+ node_attrs.append("%s=%s" % (prop, quoteattr("{" + ",".join(list(subvalue)) + "}")))
+ elif subvalue is None:
+ node_attrs.append("%s=\"NONE\"" % prop)
+ elif issubclass(subvalue_type, bpy.types.ID):
+ # special case, ID's are always referenced.
+ node_attrs.append("%s=%s" % (prop, quoteattr(subvalue_type.__name__ + "::" + subvalue.name)))
+ else:
+ try:
+ subvalue_ls = list(subvalue)
+ except:
+ subvalue_ls = None
+
+ if subvalue_ls is None:
+ nodes_items.append((prop, subvalue, subvalue_type))
+ else:
+ # check if the list contains native types
+ subvalue_rna = value.path_resolve(prop, False)
+ if type(subvalue_rna).__name__ == "bpy_prop_array":
+ # check if this is a 0-1 color (rgb, rgba)
+ # in that case write as a hexidecimal
+ prop_rna = value.bl_rna.properties[prop]
+ if (prop_rna.subtype == 'COLOR_GAMMA' and
+ prop_rna.hard_min == 0.0 and
+ prop_rna.hard_max == 1.0 and
+ prop_rna.array_length in {3, 4}):
+ # -----
+ # color
+ array_value = "#" + "".join(("%.2x" % int(v * 255) for v in subvalue_rna))
+
+ else:
+ # default
+ def str_recursive(s):
+ subsubvalue_type = type(s)
+ if subsubvalue_type in (int, float, bool):
+ return number_to_str(s, subsubvalue_type)
+ else:
+ return " ".join([str_recursive(si) for si in s])
+
+ array_value = " ".join(str_recursive(v) for v in subvalue_rna)
+
+ node_attrs.append("%s=\"%s\"" % (prop, array_value))
+ else:
+ nodes_lists.append((prop, subvalue_ls, subvalue_type))
+
+ # declare + attributes
+ if pretty_format:
+ tmp_str = "<%s " % value_type_name
+ tmp_ident = "\n" + ident + (" " * len(tmp_str))
+
+ fw("%s%s%s>\n" % (ident, tmp_str, tmp_ident.join(node_attrs)))
+
+ del tmp_str
+ del tmp_ident
+ else:
+ fw("%s<%s %s>\n" % (ident, value_type_name, " ".join(node_attrs)))
+
+ # unique members
+ for prop, subvalue, subvalue_type in nodes_items:
+ fw("%s<%s>\n" % (ident_next, prop)) # XXX, this is awkward, how best to solve?
+ rna2xml_node(ident_next + ident_val, subvalue, value)
+ fw("%s</%s>\n" % (ident_next, prop)) # XXX, need to check on this.
+
+ # list members
+ for prop, subvalue, subvalue_type in nodes_lists:
+ fw("%s<%s>\n" % (ident_next, prop))
+ for subvalue_item in subvalue:
+ if subvalue_item is not None:
+ rna2xml_node(ident_next + ident_val, subvalue_item, value)
+ fw("%s</%s>\n" % (ident_next, prop))
+
+ fw("%s</%s>\n" % (ident, value_type_name))
+
+ # -------------------------------------------------------------------------
+ # needs re-workign to be generic
+
+ if root_node:
+ fw("<%s>\n" % root_node)
+
+ # bpy.data
+ if method == 'DATA':
+ for attr in dir(root_rna):
+
+ # exceptions
+ if attr.startswith("_"):
+ continue
+ elif attr in root_rna_skip:
+ continue
+
+ value = getattr(root_rna, attr)
+ try:
+ ls = value[:]
+ except:
+ ls = None
+
+ if type(ls) == list:
+ fw("%s<%s>\n" % (ident_val, attr))
+ for blend_id in ls:
+ rna2xml_node(ident_val + ident_val, blend_id, None)
+ fw("%s</%s>\n" % (ident_val, attr))
+ # any attribute
+ elif method == 'ATTR':
+ rna2xml_node("", root_rna, None)
+
+ if root_node:
+ fw("</%s>\n" % root_node)
+
+
+def xml2rna(root_xml,
+ root_rna=None, # must be set
+ ):
+
+ def rna2xml_node(xml_node, value):
+# print("evaluating:", xml_node.nodeName)
+
+ # ---------------------------------------------------------------------
+ # Simple attributes
+
+ for attr in xml_node.attributes.keys():
+# print(" ", attr)
+ subvalue = getattr(value, attr, Ellipsis)
+
+ if subvalue is Ellipsis:
+ print("%s.%s not found" % (type(value).__name__, attr))
+ else:
+ value_xml = xml_node.attributes[attr].value
+
+ subvalue_type = type(subvalue)
+ tp_name = 'UNKNOWN'
+ if subvalue_type == float:
+ value_xml_coerce = float(value_xml)
+ tp_name = 'FLOAT'
+ elif subvalue_type == int:
+ value_xml_coerce = int(value_xml)
+ tp_name = 'INT'
+ elif subvalue_type == bool:
+ value_xml_coerce = {'TRUE': True, 'FALSE': False}[value_xml]
+ tp_name = 'BOOL'
+ elif subvalue_type == str:
+ value_xml_coerce = value_xml
+ tp_name = 'STR'
+ elif hasattr(subvalue, "__len__"):
+ if value_xml.startswith("#"):
+ # read hexidecimal value as float array
+ value_xml_split = value_xml[1:]
+ value_xml_coerce = [int(value_xml_split[i:i + 2], 16) / 255 for i in range(0, len(value_xml_split), 2)]
+ del value_xml_split
+ else:
+ value_xml_split = value_xml.split()
+ try:
+ value_xml_coerce = [int(v) for v in value_xml_split]
+ except ValueError:
+ value_xml_coerce = [float(v) for v in value_xml_split]
+ del value_xml_split
+ tp_name = 'ARRAY'
+
+# print(" %s.%s (%s) --- %s" % (type(value).__name__, attr, tp_name, subvalue_type))
+ setattr(value, attr, value_xml_coerce)
+
+ # ---------------------------------------------------------------------
+ # Complex attributes
+ for child_xml in xml_node.childNodes:
+ if child_xml.nodeType == child_xml.ELEMENT_NODE:
+ # print()
+ # print(child_xml.nodeName)
+ subvalue = getattr(value, child_xml.nodeName, None)
+ if subvalue is not None:
+
+ elems = []
+ for child_xml_real in child_xml.childNodes:
+ if child_xml_real.nodeType == child_xml_real.ELEMENT_NODE:
+ elems.append(child_xml_real)
+ del child_xml_real
+
+ if hasattr(subvalue, "__len__"):
+ # Collection
+ if len(elems) != len(subvalue):
+ print("Size Mismatch! collection:", child_xml.nodeName)
+ else:
+ for i in range(len(elems)):
+ child_xml_real = elems[i]
+ subsubvalue = subvalue[i]
+
+ if child_xml_real is None or subsubvalue is None:
+ print("None found %s - %d collection:", (child_xml.nodeName, i))
+ else:
+ rna2xml_node(child_xml_real, subsubvalue)
+
+ else:
+# print(elems)
+
+ if len(elems) == 1:
+ # sub node named by its type
+ child_xml_real, = elems
+
+ # print(child_xml_real, subvalue)
+ rna2xml_node(child_xml_real, subvalue)
+ else:
+ # empty is valid too
+ pass
+
+ rna2xml_node(root_xml, root_rna)
diff --git a/release/scripts/modules/sys_info.py b/release/scripts/modules/sys_info.py
index 64ff1c0f007..10aba96afd0 100644
--- a/release/scripts/modules/sys_info.py
+++ b/release/scripts/modules/sys_info.py
@@ -99,7 +99,7 @@ def write_sysinfo(op):
ffmpeg = bpy.app.ffmpeg
if ffmpeg.supported:
for lib in ['avcodec', 'avdevice', 'avformat', 'avutil', 'swscale']:
- output.write('{}:{}{}\n'.format(lib, " "*(10-len(lib)),
+ output.write('{}:{}{}\n'.format(lib, " " * (10 - len(lib)),
getattr(ffmpeg, lib + '_version_string')))
else:
output.write('Blender was built without FFmpeg support\n')
diff --git a/release/scripts/startup/bl_operators/anim.py b/release/scripts/startup/bl_operators/anim.py
index 01103aede0d..29e8a396088 100644
--- a/release/scripts/startup/bl_operators/anim.py
+++ b/release/scripts/startup/bl_operators/anim.py
@@ -239,7 +239,7 @@ class ClearUselessActions(Operator):
@classmethod
def poll(cls, context):
- return len(bpy.data.actions) != 0
+ return bool(bpy.data.actions)
def execute(self, context):
removed = 0
diff --git a/release/scripts/startup/bl_operators/clip.py b/release/scripts/startup/bl_operators/clip.py
index cb21f17cff5..28628a48a0b 100644
--- a/release/scripts/startup/bl_operators/clip.py
+++ b/release/scripts/startup/bl_operators/clip.py
@@ -24,7 +24,7 @@ from bpy.types import Operator
from mathutils import Vector, Matrix
-def CLIP_spacees_walk(context, all_screens, tarea, tspace, callback, *args):
+def CLIP_spaces_walk(context, all_screens, tarea, tspace, callback, *args):
screens = bpy.data.screens if all_screens else [context.screen]
for screen in screens:
@@ -56,10 +56,26 @@ def CLIP_set_viewport_background(context, all_screens, clip, clip_user):
space_v3d.show_background_images = True
- CLIP_spacees_walk(context, all_screens, 'VIEW_3D', 'VIEW_3D',
+ CLIP_spaces_walk(context, all_screens, 'VIEW_3D', 'VIEW_3D',
set_background, clip, clip_user)
+def CLIP_camera_for_clip(context, clip):
+ scene = context.scene
+
+ camera = scene.camera
+
+ for ob in scene.objects:
+ if ob.type == 'CAMERA':
+ for con in ob.constraints:
+ if con.type == 'CAMERA_SOLVER':
+ cur_clip = scene.clip if con.use_active_clip else con.clip
+
+ if cur_clip == clip:
+ return ob
+
+ return camera
+
def CLIP_track_view_selected(sc, track):
if track.select_anchor:
return True
@@ -80,7 +96,7 @@ class CLIP_OT_track_to_empty(Operator):
bl_label = "Link Empty to Track"
bl_options = {'UNDO', 'REGISTER'}
- def _link_track(self, context, track):
+ def _link_track(self, context, clip, tracking_object, track):
sc = context.space_data
constraint = None
ob = None
@@ -101,14 +117,17 @@ class CLIP_OT_track_to_empty(Operator):
constraint.clip = sc.clip
constraint.track = track.name
constraint.use_3d_position = False
+ constraint.object = tracking_object.name
+ constraint.camera = CLIP_camera_for_clip(context, clip);
def execute(self, context):
sc = context.space_data
clip = sc.clip
+ tracking_object = clip.tracking.objects.active
- for track in clip.tracking.tracks:
+ for track in tracking_object.tracks:
if CLIP_track_view_selected(sc, track):
- self._link_track(context, track)
+ self._link_track(context, clip, tracking_object ,track)
return {'FINISHED'}
@@ -130,11 +149,12 @@ class CLIP_OT_bundles_to_mesh(Operator):
sc = context.space_data
clip = sc.clip
+ tracking_object = clip.tracking.objects.active
new_verts = []
mesh = bpy.data.meshes.new(name="Tracks")
- for track in clip.tracking.tracks:
+ for track in tracking_object.tracks:
if track.has_bundle:
new_verts.append(track.bundle)
@@ -269,7 +289,7 @@ object's movement caused by this constraint"""
# TODO: several camera solvers and track followers would fail,
# but can't think about eal workflow where it'll be useful
for x in ob.constraints:
- if x.type in {'CAMERA_SOLVER', 'FOLLOW_TRACK'}:
+ if x.type in {'CAMERA_SOLVER', 'FOLLOW_TRACK', 'OBJECT_SOLVER'}:
con = x
if not con:
@@ -509,7 +529,7 @@ class CLIP_OT_setup_tracking_scene(Operator):
def setup_space(space):
space.show_backdrop = True
- CLIP_spacees_walk(context, True, 'NODE_EDITOR', 'NODE_EDITOR',
+ CLIP_spaces_walk(context, True, 'NODE_EDITOR', 'NODE_EDITOR',
setup_space)
sc = context.space_data
diff --git a/release/scripts/startup/bl_operators/object_randomize_transform.py b/release/scripts/startup/bl_operators/object_randomize_transform.py
index fa36e48d47b..d3d70f892b8 100644
--- a/release/scripts/startup/bl_operators/object_randomize_transform.py
+++ b/release/scripts/startup/bl_operators/object_randomize_transform.py
@@ -49,7 +49,7 @@ def randomize_selected(seed, delta, loc, rot, scale, scale_even, scale_min):
rotation_mode = obj.rotation_mode
if rotation_mode in {'QUATERNION', 'AXIS_ANGLE'}:
obj.rotation_mode = 'XYZ'
-
+
if delta:
obj.delta_rotation_euler[0] += vec[0]
obj.delta_rotation_euler[1] += vec[1]
diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py
index 4f498e72f4b..11326377a79 100644
--- a/release/scripts/startup/bl_operators/wm.py
+++ b/release/scripts/startup/bl_operators/wm.py
@@ -32,6 +32,7 @@ from rna_prop_ui import rna_idprop_ui_prop_get, rna_idprop_ui_prop_clear
import subprocess
import os
+
class MESH_OT_delete_edgeloop(Operator):
'''Delete an edge loop by merging the faces on each side to a single face loop'''
bl_idname = "mesh.delete_edgeloop"
@@ -501,9 +502,9 @@ class WM_MT_context_menu_enum(Menu):
values = [(i.name, i.identifier) for i in value_base.bl_rna.properties[prop_string].enum_items]
for name, identifier in values:
- prop = self.layout.operator("wm.context_set_enum", text=name)
- prop.data_path = data_path
- prop.value = identifier
+ props = self.layout.operator("wm.context_set_enum", text=name)
+ props.data_path = data_path
+ props.value = identifier
class WM_OT_context_menu_enum(Operator):
@@ -1176,27 +1177,29 @@ class WM_OT_copy_prev_settings(Operator):
return {'CANCELLED'}
+
class WM_OT_blenderplayer_start(bpy.types.Operator):
'''Launch the Blenderplayer with the current blendfile'''
bl_idname = "wm.blenderplayer_start"
bl_label = "Start"
-
+
blender_bin_path = bpy.app.binary_path
blender_bin_dir = os.path.dirname(blender_bin_path)
ext = os.path.splitext(blender_bin_path)[-1]
player_path = os.path.join(blender_bin_dir, "blenderplayer" + ext)
-
+
def execute(self, context):
import sys
if sys.platform == "darwin":
self.player_path = os.path.join(self.blender_bin_dir, "../../../blenderplayer.app/Contents/MacOS/blenderplayer")
-
+
filepath = bpy.app.tempdir + "game.blend"
bpy.ops.wm.save_as_mainfile(filepath=filepath, check_existing=False, copy=True)
subprocess.call([self.player_path, filepath])
return {'FINISHED'}
+
class WM_OT_keyconfig_test(Operator):
"Test keyconfig for conflicts"
bl_idname = "wm.keyconfig_test"
@@ -1463,6 +1466,9 @@ class WM_OT_operator_cheat_sheet(Operator):
return {'FINISHED'}
+# -----------------------------------------------------------------------------
+# Addon Operators
+
class WM_OT_addon_enable(Operator):
"Enable an addon"
bl_idname = "wm.addon_enable"
@@ -1762,3 +1768,61 @@ class WM_OT_addon_expand(Operator):
info = addon_utils.module_bl_info(mod)
info["show_expanded"] = not info["show_expanded"]
return {'FINISHED'}
+
+
+# -----------------------------------------------------------------------------
+# Theme IO
+from bpy_extras.io_utils import (ImportHelper,
+ ExportHelper,
+ )
+
+
+class WM_OT_theme_import(Operator, ImportHelper):
+ bl_idname = "wm.theme_import"
+ bl_label = "Import Theme"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ filename_ext = ".xml"
+ filter_glob = StringProperty(default="*.xml", options={'HIDDEN'})
+
+ def execute(self, context):
+ import rna_xml
+ import xml.dom.minidom
+
+ filepath = self.filepath
+
+ xml_nodes = xml.dom.minidom.parse(filepath)
+ theme_xml = xml_nodes.getElementsByTagName("Theme")[0]
+
+ # XXX, why always 0?, allow many?
+ theme = context.user_preferences.themes[0]
+
+ rna_xml.xml2rna(theme_xml,
+ root_rna=theme,
+ )
+
+ return {'FINISHED'}
+
+
+class WM_OT_theme_export(Operator, ExportHelper):
+ bl_idname = "wm.theme_export"
+ bl_label = "Export Theme"
+
+ filename_ext = ".xml"
+ filter_glob = StringProperty(default="*.xml", options={'HIDDEN'})
+
+ def execute(self, context):
+ import rna_xml
+
+ filepath = self.filepath
+ file = open(filepath, 'w', encoding='utf-8')
+
+ # XXX, why always 0?, allow many?
+ theme = context.user_preferences.themes[0]
+
+ rna_xml.rna2xml(file.write,
+ root_rna=theme,
+ method='ATTR',
+ )
+
+ return {'FINISHED'}
diff --git a/release/scripts/startup/bl_ui/properties_data_curve.py b/release/scripts/startup/bl_ui/properties_data_curve.py
index 02e13966c48..79d722eb19d 100644
--- a/release/scripts/startup/bl_ui/properties_data_curve.py
+++ b/release/scripts/startup/bl_ui/properties_data_curve.py
@@ -214,12 +214,11 @@ class DATA_PT_active_spline(CurveButtonsPanelActive, Panel):
if is_poly:
# These settings are below but its easier to have
# poly's set aside since they use so few settings
- col = split.column()
- col.label(text="Cyclic:")
- col.prop(act_spline, "use_smooth")
- col = split.column()
- col.prop(act_spline, "use_cyclic_u", text="U")
+ row = layout.row()
+ row.label(text="Cyclic:")
+ row.prop(act_spline, "use_cyclic_u", text="U")
+ layout.prop(act_spline, "use_smooth")
else:
col = split.column()
col.label(text="Cyclic:")
@@ -257,13 +256,13 @@ class DATA_PT_active_spline(CurveButtonsPanelActive, Panel):
sub.prop(act_spline, "resolution_v", text="V")
if not is_surf:
- split = layout.split()
- col = split.column()
-
+ col = layout.column()
col.label(text="Interpolation:")
- colsub = col.column()
- colsub.active = (curve.dimensions == '3D')
- colsub.prop(act_spline, "tilt_interpolation", text="Tilt")
+
+ sub = col.column()
+ sub.active = (curve.dimensions == '3D')
+ sub.prop(act_spline, "tilt_interpolation", text="Tilt")
+
col.prop(act_spline, "radius_interpolation", text="Radius")
layout.prop(act_spline, "use_smooth")
diff --git a/release/scripts/startup/bl_ui/properties_data_mesh.py b/release/scripts/startup/bl_ui/properties_data_mesh.py
index fa59cc0ac53..5be9e57356c 100644
--- a/release/scripts/startup/bl_ui/properties_data_mesh.py
+++ b/release/scripts/startup/bl_ui/properties_data_mesh.py
@@ -158,7 +158,7 @@ class DATA_PT_vertex_groups(MeshButtonsPanel, Panel):
row = layout.row()
row.prop(group, "name")
- if ob.mode == 'EDIT' and len(ob.vertex_groups) > 0:
+ if ob.vertex_groups and (ob.mode == 'EDIT' or (ob.mode == 'WEIGHT_PAINT' and ob.type == 'MESH' and ob.data.use_paint_mask_vertex)):
row = layout.row()
sub = row.row(align=True)
diff --git a/release/scripts/startup/bl_ui/properties_game.py b/release/scripts/startup/bl_ui/properties_game.py
index 355a6771022..b7b2acc6b08 100644
--- a/release/scripts/startup/bl_ui/properties_game.py
+++ b/release/scripts/startup/bl_ui/properties_game.py
@@ -247,6 +247,7 @@ class RenderButtonsPanel():
class RENDER_PT_embedded(RenderButtonsPanel, bpy.types.Panel):
bl_label = "Embedded Player"
COMPAT_ENGINES = {'BLENDER_GAME'}
+
def draw(self, context):
layout = self.layout
@@ -270,17 +271,17 @@ class RENDER_PT_game_player(RenderButtonsPanel, Panel):
layout = self.layout
gs = context.scene.game_settings
-
+
row = layout.row()
row.operator("wm.blenderplayer_start", text="Start")
row.prop(gs, "show_fullscreen")
-
+
row = layout.row()
row.label(text="Resolution:")
row = layout.row(align=True)
row.prop(gs, "resolution_x", slider=False, text="X")
row.prop(gs, "resolution_y", slider=False, text="Y")
-
+
col = layout.column()
col.label(text="Quality:")
col = layout.column(align=True)
@@ -288,7 +289,6 @@ class RENDER_PT_game_player(RenderButtonsPanel, Panel):
col.prop(gs, "frequency", text="Refresh Rate", slider=False)
-
class RENDER_PT_game_stereo(RenderButtonsPanel, Panel):
bl_label = "Stereo"
COMPAT_ENGINES = {'BLENDER_GAME'}
@@ -476,6 +476,7 @@ class SCENE_PT_game_navmesh(SceneButtonsPanel, Panel):
row.prop(rd, "sample_dist")
row.prop(rd, "sample_max_error")
+
class RENDER_PT_game_sound(RenderButtonsPanel, Panel):
bl_label = "Sound"
COMPAT_ENGINES = {'BLENDER_GAME'}
@@ -491,6 +492,7 @@ class RENDER_PT_game_sound(RenderButtonsPanel, Panel):
col.prop(scene, "audio_doppler_speed", text="Speed")
col.prop(scene, "audio_doppler_factor")
+
class WorldButtonsPanel():
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
diff --git a/release/scripts/startup/bl_ui/properties_object.py b/release/scripts/startup/bl_ui/properties_object.py
index 27b6aa721a4..f01c2ba45e0 100644
--- a/release/scripts/startup/bl_ui/properties_object.py
+++ b/release/scripts/startup/bl_ui/properties_object.py
@@ -181,9 +181,9 @@ class OBJECT_PT_groups(ObjectButtonsPanel, Panel):
col = split.column()
col.prop(group, "dupli_offset", text="")
- prop = col.operator("wm.context_set_value", text="From Cursor")
- prop.data_path = "object.users_group[%d].dupli_offset" % index
- prop.value = value
+ props = col.operator("wm.context_set_value", text="From Cursor")
+ props.data_path = "object.users_group[%d].dupli_offset" % index
+ props.value = value
index += 1
diff --git a/release/scripts/startup/bl_ui/properties_object_constraint.py b/release/scripts/startup/bl_ui/properties_object_constraint.py
index 32ed1c3f1b1..57adfa1fa20 100644
--- a/release/scripts/startup/bl_ui/properties_object_constraint.py
+++ b/release/scripts/startup/bl_ui/properties_object_constraint.py
@@ -774,10 +774,14 @@ class ConstraintButtonsPanel():
if clip:
layout.prop_search(con, "object", clip.tracking, "objects", icon='OBJECT_DATA')
- layout.prop_search(con, "track", clip.tracking, "tracks", icon='ANIMATION_DATA')
+ layout.prop_search(con, "track", clip.tracking, "tracks", icon='ANIM_DATA')
layout.prop(con, "camera")
+ row = layout.row()
+ row.active = not con.use_3d_position
+ row.prop(con, "depth_object")
+
layout.operator("clip.constraint_to_fcurve")
def CAMERA_SOLVER(self, context, layout, con):
diff --git a/release/scripts/startup/bl_ui/properties_particle.py b/release/scripts/startup/bl_ui/properties_particle.py
index b19cf0032af..5e68351d9e6 100644
--- a/release/scripts/startup/bl_ui/properties_particle.py
+++ b/release/scripts/startup/bl_ui/properties_particle.py
@@ -85,7 +85,7 @@ class PARTICLE_PT_context_particles(ParticleButtonsPanel, Panel):
def draw(self, context):
layout = self.layout
-
+
if context.scene.render.engine == "BLENDER_GAME":
layout.label("Not available in the Game Engine")
return
diff --git a/release/scripts/startup/bl_ui/properties_render.py b/release/scripts/startup/bl_ui/properties_render.py
index 8ac178edcb1..62e39020764 100644
--- a/release/scripts/startup/bl_ui/properties_render.py
+++ b/release/scripts/startup/bl_ui/properties_render.py
@@ -963,6 +963,12 @@ class RENDER_PT_stamp(RenderButtonsPanel, Panel):
rd = context.scene.render
layout.active = rd.use_stamp
+
+ layout.prop(rd, "stamp_font_size", text="Font Size")
+
+ row = layout.row()
+ row.column().prop(rd, "stamp_foreground", slider=True)
+ row.column().prop(rd, "stamp_background", slider=True)
split = layout.split()
@@ -972,19 +978,14 @@ class RENDER_PT_stamp(RenderButtonsPanel, Panel):
col.prop(rd, "use_stamp_render_time", text="RenderTime")
col.prop(rd, "use_stamp_frame", text="Frame")
col.prop(rd, "use_stamp_scene", text="Scene")
+
+ col = split.column()
col.prop(rd, "use_stamp_camera", text="Camera")
col.prop(rd, "use_stamp_lens", text="Lens")
col.prop(rd, "use_stamp_filename", text="Filename")
col.prop(rd, "use_stamp_marker", text="Marker")
col.prop(rd, "use_stamp_sequencer_strip", text="Seq. Strip")
- col = split.column()
- col.active = rd.use_stamp
- col.prop(rd, "stamp_foreground", slider=True)
- col.prop(rd, "stamp_background", slider=True)
- col.separator()
- col.prop(rd, "stamp_font_size", text="Font Size")
-
row = layout.split(percentage=0.2)
row.prop(rd, "use_stamp_note", text="Note")
sub = row.row()
diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py
index 0da022dd8db..62889baf550 100644
--- a/release/scripts/startup/bl_ui/space_clip.py
+++ b/release/scripts/startup/bl_ui/space_clip.py
@@ -317,9 +317,10 @@ class CLIP_PT_tools_object(Panel):
return False
def draw(self, context):
+ layout = self.layout
+
sc = context.space_data
clip = sc.clip
- layout = self.layout
tracking_object = clip.tracking.objects.active
settings = sc.clip.tracking.settings
@@ -376,9 +377,9 @@ class CLIP_PT_objects(Panel):
def draw(self, context):
layout = self.layout
+
sc = context.space_data
- clip = sc.clip
- tracking = clip.tracking
+ tracking = sc.clip.tracking
row = layout.row()
row.template_list(tracking, "objects",
diff --git a/release/scripts/startup/bl_ui/space_image.py b/release/scripts/startup/bl_ui/space_image.py
index 81526797109..4ccdef747ce 100644
--- a/release/scripts/startup/bl_ui/space_image.py
+++ b/release/scripts/startup/bl_ui/space_image.py
@@ -298,34 +298,34 @@ class IMAGE_MT_uvs_select_mode(Menu):
# do smart things depending on whether uv_select_sync is on
if toolsettings.use_uv_select_sync:
- prop = layout.operator("wm.context_set_value", text="Vertex", icon='VERTEXSEL')
- prop.value = "(True, False, False)"
- prop.data_path = "tool_settings.mesh_select_mode"
+ props = layout.operator("wm.context_set_value", text="Vertex", icon='VERTEXSEL')
+ props.value = "(True, False, False)"
+ props.data_path = "tool_settings.mesh_select_mode"
- prop = layout.operator("wm.context_set_value", text="Edge", icon='EDGESEL')
- prop.value = "(False, True, False)"
- prop.data_path = "tool_settings.mesh_select_mode"
+ props = layout.operator("wm.context_set_value", text="Edge", icon='EDGESEL')
+ props.value = "(False, True, False)"
+ props.data_path = "tool_settings.mesh_select_mode"
- prop = layout.operator("wm.context_set_value", text="Face", icon='FACESEL')
- prop.value = "(False, False, True)"
- prop.data_path = "tool_settings.mesh_select_mode"
+ props = layout.operator("wm.context_set_value", text="Face", icon='FACESEL')
+ props.value = "(False, False, True)"
+ props.data_path = "tool_settings.mesh_select_mode"
else:
- prop = layout.operator("wm.context_set_string", text="Vertex", icon='UV_VERTEXSEL')
- prop.value = 'VERTEX'
- prop.data_path = "tool_settings.uv_select_mode"
+ props = layout.operator("wm.context_set_string", text="Vertex", icon='UV_VERTEXSEL')
+ props.value = 'VERTEX'
+ props.data_path = "tool_settings.uv_select_mode"
- prop = layout.operator("wm.context_set_string", text="Edge", icon='UV_EDGESEL')
- prop.value = 'EDGE'
- prop.data_path = "tool_settings.uv_select_mode"
+ props = layout.operator("wm.context_set_string", text="Edge", icon='UV_EDGESEL')
+ props.value = 'EDGE'
+ props.data_path = "tool_settings.uv_select_mode"
- prop = layout.operator("wm.context_set_string", text="Face", icon='UV_FACESEL')
- prop.value = 'FACE'
- prop.data_path = "tool_settings.uv_select_mode"
+ props = layout.operator("wm.context_set_string", text="Face", icon='UV_FACESEL')
+ props.value = 'FACE'
+ props.data_path = "tool_settings.uv_select_mode"
- prop = layout.operator("wm.context_set_string", text="Island", icon='UV_ISLANDSEL')
- prop.value = 'ISLAND'
- prop.data_path = "tool_settings.uv_select_mode"
+ props = layout.operator("wm.context_set_string", text="Island", icon='UV_ISLANDSEL')
+ props.value = 'ISLAND'
+ props.data_path = "tool_settings.uv_select_mode"
class IMAGE_HT_header(Header):
diff --git a/release/scripts/startup/bl_ui/space_logic.py b/release/scripts/startup/bl_ui/space_logic.py
index 1fc58475ace..1d0e2221ce2 100644
--- a/release/scripts/startup/bl_ui/space_logic.py
+++ b/release/scripts/startup/bl_ui/space_logic.py
@@ -36,11 +36,34 @@ class LOGIC_PT_properties(Panel):
ob = context.active_object
game = ob.game
+ is_font = (ob.type == 'FONT')
+
+ if is_font:
+ prop_index = game.properties.find("Text")
+ if prop_index != -1:
+ layout.operator("object.game_property_remove", text="Renove Text Game Property", icon='X').index = prop_index
+ row = layout.row()
+ sub = row.row()
+ sub.enabled = 0
+ prop = game.properties[prop_index]
+ sub.prop(prop, "name", text="")
+ row.prop(prop, "type", text="")
+ # get the property from the body, not the game property
+ # note, dont do this - its too slow and body can potentually be a really long string.
+ # row.prop(ob.data, "body", text="")
+ row.label("See Font Object")
+ else:
+ props = layout.operator("object.game_property_new", text="Add Text Game Property", icon='ZOOMIN')
+ props.name = 'Text'
+ props.type = 'STRING'
layout.operator("object.game_property_new", text="Add Game Property", icon='ZOOMIN')
for i, prop in enumerate(game.properties):
+ if is_font and i == prop_index:
+ continue
+
box = layout.box()
row = box.row()
row.prop(prop, "name", text="")
diff --git a/release/scripts/startup/bl_ui/space_node.py b/release/scripts/startup/bl_ui/space_node.py
index 318ba8eab8a..edbcf3ecf5b 100644
--- a/release/scripts/startup/bl_ui/space_node.py
+++ b/release/scripts/startup/bl_ui/space_node.py
@@ -28,6 +28,7 @@ class NODE_HT_header(Header):
layout = self.layout
scene = context.scene
+ ob = context.object
snode = context.space_data
snode_id = snode.id
id_from = snode.id_from
@@ -47,10 +48,15 @@ class NODE_HT_header(Header):
if scene.render.use_shading_nodes:
layout.prop(snode, "shader_type", text="", expand=True)
- if not scene.render.use_shading_nodes or snode.shader_type == 'OBJECT':
- if id_from:
+ if (not scene.render.use_shading_nodes or snode.shader_type == 'OBJECT') and ob:
+ # Show material.new when no active ID/slot exists
+ if not id_from and ob.type in {'MESH', 'CURVE', 'SURFACE', 'FONT', 'METABALL'}:
+ layout.template_ID(ob, "active_material", new="material.new")
+ # Material ID, but not for Lamps
+ if id_from and ob.type != 'LAMP':
layout.template_ID(id_from, "active_material", new="material.new")
- if snode_id:
+ # Don't show "Use Nodes" Button when Engine is BI for Lamps
+ if snode_id and not (scene.render.use_shading_nodes == 0 and ob.type == 'LAMP'):
layout.prop(snode_id, "use_nodes")
elif snode.tree_type == 'TEXTURE':
diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py
index df8c085d77e..046026a3b6e 100644
--- a/release/scripts/startup/bl_ui/space_userpref.py
+++ b/release/scripts/startup/bl_ui/space_userpref.py
@@ -89,13 +89,15 @@ class USERPREF_HT_header(Header):
layout.operator_context = 'INVOKE_DEFAULT'
if userpref.active_section == 'INPUT':
- layout.operator("wm.keyconfig_export")
layout.operator("wm.keyconfig_import")
+ layout.operator("wm.keyconfig_export")
elif userpref.active_section == 'ADDONS':
layout.operator("wm.addon_install")
layout.menu("USERPREF_MT_addons_dev_guides")
elif userpref.active_section == 'THEMES':
layout.operator("ui.reset_default_theme")
+ layout.operator("wm.theme_import")
+ layout.operator("wm.theme_export")
class USERPREF_PT_tabs(Panel):
diff --git a/release/scripts/startup/bl_ui/space_userpref_keymap.py b/release/scripts/startup/bl_ui/space_userpref_keymap.py
index d738e806320..6fa3aabaeb8 100644
--- a/release/scripts/startup/bl_ui/space_userpref_keymap.py
+++ b/release/scripts/startup/bl_ui/space_userpref_keymap.py
@@ -219,7 +219,7 @@ class InputKeyMapPanel:
filtered_items = [kmi for kmi in km.keymap_items if filter_text in kmi.name.lower()]
- if len(filtered_items) != 0:
+ if filtered_items:
col = layout.column()
row = col.row()
diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index f018e6fc86f..1223b8f25df 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -1052,7 +1052,7 @@ class VIEW3D_MT_vertex_group(Menu):
layout.operator("object.vertex_group_assign", text="Assign to New Group").new = True
ob = context.active_object
- if ob.mode == 'EDIT':
+ if ob.mode == 'EDIT' or (ob.mode == 'WEIGHT_PAINT' and ob.type == 'MESH' and ob.data.use_paint_mask_vertex):
if ob.vertex_groups.active:
layout.separator()
layout.operator("object.vertex_group_assign", text="Assign to Active Group")
@@ -1523,17 +1523,17 @@ class VIEW3D_MT_edit_mesh_select_mode(Menu):
layout.operator_context = 'INVOKE_REGION_WIN'
- prop = layout.operator("wm.context_set_value", text="Vertex", icon='VERTEXSEL')
- prop.value = "(True, False, False)"
- prop.data_path = "tool_settings.mesh_select_mode"
+ props = layout.operator("wm.context_set_value", text="Vertex", icon='VERTEXSEL')
+ props.value = "(True, False, False)"
+ props.data_path = "tool_settings.mesh_select_mode"
- prop = layout.operator("wm.context_set_value", text="Edge", icon='EDGESEL')
- prop.value = "(False, True, False)"
- prop.data_path = "tool_settings.mesh_select_mode"
+ props = layout.operator("wm.context_set_value", text="Edge", icon='EDGESEL')
+ props.value = "(False, True, False)"
+ props.data_path = "tool_settings.mesh_select_mode"
- prop = layout.operator("wm.context_set_value", text="Face", icon='FACESEL')
- prop.value = "(False, False, True)"
- prop.data_path = "tool_settings.mesh_select_mode"
+ props = layout.operator("wm.context_set_value", text="Face", icon='FACESEL')
+ props.value = "(False, False, True)"
+ props.data_path = "tool_settings.mesh_select_mode"
class VIEW3D_MT_edit_mesh_extrude(Menu):
@@ -2260,7 +2260,7 @@ class VIEW3D_PT_view3d_meshdisplay(Panel):
col.prop(mesh, "show_extra_face_angle")
col.prop(mesh, "show_extra_face_area")
if bpy.app.debug:
- col.prop(mesh, "show_extra_indices")
+ col.prop(mesh, "show_extra_indices")
class VIEW3D_PT_view3d_curvedisplay(Panel):
@@ -2381,13 +2381,14 @@ class VIEW3D_PT_transform_orientations(Panel):
view = context.space_data
orientation = view.current_orientation
- col = layout.column()
- col.prop(view, "transform_orientation")
- col.operator("transform.create_orientation", text="Create")
+ row = layout.row(align=True)
+ row.prop(view, "transform_orientation", text="")
+ row.operator("transform.create_orientation", text="", icon='ZOOMIN')
if orientation:
- col.prop(orientation, "name")
- col.operator("transform.delete_orientation", text="Delete")
+ row = layout.row(align=True)
+ row.prop(orientation, "name", text="")
+ row.operator("transform.delete_orientation", text="", icon="X")
class VIEW3D_PT_etch_a_ton(Panel):
diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
index 9644f57d6cd..25f81f2cde1 100644
--- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
@@ -1198,9 +1198,9 @@ class VIEW3D_MT_tools_projectpaint_clone(Menu):
def draw(self, context):
layout = self.layout
for i, tex in enumerate(context.active_object.data.uv_textures):
- prop = layout.operator("wm.context_set_int", text=tex.name)
- prop.data_path = "active_object.data.uv_texture_clone_index"
- prop.value = i
+ props = layout.operator("wm.context_set_int", text=tex.name)
+ props.data_path = "active_object.data.uv_texture_clone_index"
+ props.value = i
class VIEW3D_MT_tools_projectpaint_stencil(Menu):
@@ -1209,9 +1209,9 @@ class VIEW3D_MT_tools_projectpaint_stencil(Menu):
def draw(self, context):
layout = self.layout
for i, tex in enumerate(context.active_object.data.uv_textures):
- prop = layout.operator("wm.context_set_int", text=tex.name)
- prop.data_path = "active_object.data.uv_texture_stencil_index"
- prop.value = i
+ props = layout.operator("wm.context_set_int", text=tex.name)
+ props.data_path = "active_object.data.uv_texture_stencil_index"
+ props.value = i
class VIEW3D_PT_tools_particlemode(View3DPanel, Panel):
diff --git a/source/blender/blenfont/intern/blf.c b/source/blender/blenfont/intern/blf.c
index 9b26e7a54be..a387b416c38 100644
--- a/source/blender/blenfont/intern/blf.c
+++ b/source/blender/blenfont/intern/blf.c
@@ -479,7 +479,7 @@ void BLF_rotation_default(float angle)
}
}
-static void blf_draw__start(FontBLF *font)
+static void blf_draw__start(FontBLF *font, GLint *mode, GLint *param)
{
/*
* The pixmap alignment hack is handle
@@ -490,6 +490,14 @@ static void blf_draw__start(FontBLF *font)
glEnable(GL_TEXTURE_2D);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ /* Save the current matrix mode. */
+ glGetIntegerv(GL_MATRIX_MODE, mode);
+
+ glMatrixMode(GL_TEXTURE);
+ glPushMatrix();
+ glLoadIdentity();
+
+ glMatrixMode(GL_MODELVIEW);
glPushMatrix();
if (font->flags & BLF_MATRIX)
@@ -509,11 +517,27 @@ static void blf_draw__start(FontBLF *font)
/* always bind the texture for the first glyph */
font->tex_bind_state= -1;
+ /* Save the current parameter to restore it later. */
+ glGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, param);
+ if (*param != GL_MODULATE)
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
}
-static void blf_draw__end(void)
+static void blf_draw__end(GLint mode, GLint param)
{
+ /* and restore the original value. */
+ if (param != GL_MODULATE)
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, param);
+
+ glMatrixMode(GL_TEXTURE);
glPopMatrix();
+
+ glMatrixMode(GL_MODELVIEW);
+ glPopMatrix();
+
+ if (mode != GL_MODELVIEW)
+ glMatrixMode(mode);
+
glDisable(GL_BLEND);
glDisable(GL_TEXTURE_2D);
}
@@ -521,22 +545,24 @@ static void blf_draw__end(void)
void BLF_draw(int fontid, const char *str, size_t len)
{
FontBLF *font= BLF_get(fontid);
+ GLint mode, param;
if (font && font->glyph_cache) {
- blf_draw__start(font);
+ blf_draw__start(font, &mode, &param);
blf_font_draw(font, str, len);
- blf_draw__end();
+ blf_draw__end(mode, param);
}
}
void BLF_draw_ascii(int fontid, const char *str, size_t len)
{
FontBLF *font= BLF_get(fontid);
+ GLint mode, param;
if (font && font->glyph_cache) {
- blf_draw__start(font);
+ blf_draw__start(font, &mode, &param);
blf_font_draw_ascii(font, str, len);
- blf_draw__end();
+ blf_draw__end(mode, param);
}
}
diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h
index cb4fba43f8d..49cde9d6517 100644
--- a/source/blender/blenkernel/BKE_blender.h
+++ b/source/blender/blenkernel/BKE_blender.h
@@ -42,7 +42,7 @@ extern "C" {
* and keep comment above the defines.
* Use STRINGIFY() rather than defining with quotes */
#define BLENDER_VERSION 261
-#define BLENDER_SUBVERSION 0
+#define BLENDER_SUBVERSION 1
#define BLENDER_MINVERSION 250
#define BLENDER_MINSUBVERSION 0
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index 6234308048b..9fdae5b190e 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -374,6 +374,8 @@ int nodeUpdateID(struct bNodeTree *ntree, struct ID *id);
void nodeFreePreview(struct bNode *node);
+int nodeSocketIsHidden(struct bNodeSocket *sock);
+
/* ************** NODE TYPE ACCESS *************** */
struct bNodeTemplate nodeMakeTemplate(struct bNode *node);
diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h
index f491761f3f2..dbefbd95a15 100644
--- a/source/blender/blenkernel/BKE_particle.h
+++ b/source/blender/blenkernel/BKE_particle.h
@@ -63,7 +63,8 @@ struct BVHTreeRayHit;
#define LOOP_PARTICLES for(p=0, pa=psys->particles; p<psys->totpart; p++, pa++)
#define LOOP_EXISTING_PARTICLES for(p=0, pa=psys->particles; p<psys->totpart; p++, pa++) if(!(pa->flag & PARS_UNEXIST))
#define LOOP_SHOWN_PARTICLES for(p=0, pa=psys->particles; p<psys->totpart; p++, pa++) if(!(pa->flag & (PARS_UNEXIST|PARS_NO_DISP)))
-#define LOOP_DYNAMIC_PARTICLES for(p=0, pa=psys->particles; p<psys->totpart; p++, pa++) if(pa->state.time > 0.f)
+/* OpenMP: Can only advance one variable within loop definition. */
+#define LOOP_DYNAMIC_PARTICLES for(p=0; p<psys->totpart; p++ ) if((pa=psys->particles+p)->state.time > 0.f)
#define PSYS_FRAND_COUNT 1024
#define PSYS_FRAND(seed) psys->frand[(seed) % PSYS_FRAND_COUNT]
diff --git a/source/blender/blenkernel/BKE_sound.h b/source/blender/blenkernel/BKE_sound.h
index 57746f3a68f..fdf1d09559d 100644
--- a/source/blender/blenkernel/BKE_sound.h
+++ b/source/blender/blenkernel/BKE_sound.h
@@ -94,14 +94,17 @@ void sound_update_fps(struct Scene *scene);
void sound_update_scene_listener(struct Scene *scene);
void* sound_scene_add_scene_sound(struct Scene *scene, struct Sequence* sequence, int startframe, int endframe, int frameskip);
+void* sound_scene_add_scene_sound_defaults(struct Scene *scene, struct Sequence* sequence);
void* sound_add_scene_sound(struct Scene *scene, struct Sequence* sequence, int startframe, int endframe, int frameskip);
+void* sound_add_scene_sound_defaults(struct Scene *scene, struct Sequence* sequence);
void sound_remove_scene_sound(struct Scene *scene, void* handle);
void sound_mute_scene_sound(void* handle, char mute);
void sound_move_scene_sound(struct Scene *scene, void* handle, int startframe, int endframe, int frameskip);
+void sound_move_scene_sound_defaults(struct Scene *scene, struct Sequence *sequence);
void sound_update_scene_sound(void* handle, struct bSound* sound);
diff --git a/source/blender/blenkernel/intern/bvhutils.c b/source/blender/blenkernel/intern/bvhutils.c
index 1100c1c0ef5..1aad0a242f9 100644
--- a/source/blender/blenkernel/intern/bvhutils.c
+++ b/source/blender/blenkernel/intern/bvhutils.c
@@ -52,7 +52,7 @@ float bvhtree_ray_tri_intersection(const BVHTreeRay *ray, const float UNUSED(m_d
{
float dist;
- if(isect_ray_tri_v3(ray->origin, ray->direction, v0, v1, v2, &dist, NULL))
+ if(isect_ray_tri_epsilon_v3(ray->origin, ray->direction, v0, v1, v2, &dist, NULL, FLT_EPSILON))
return dist;
return FLT_MAX;
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index 878db6b3ed1..77a4a6a429c 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -41,6 +41,7 @@
#include "BLI_blenlib.h"
#include "BLI_math.h"
#include "BLI_editVert.h"
+#include "BLI_kdopbvh.h"
#include "BLI_utildefines.h"
#include "DNA_armature_types.h"
@@ -64,6 +65,7 @@
#include "BKE_anim.h" /* for the curve calculation part */
#include "BKE_armature.h"
#include "BKE_blender.h"
+#include "BKE_bvhutils.h"
#include "BKE_camera.h"
#include "BKE_constraint.h"
#include "BKE_displist.h"
@@ -3950,6 +3952,7 @@ static void followtrack_id_looper (bConstraint *con, ConstraintIDFunc func, void
func(con, (ID**)&data->clip, userdata);
func(con, (ID**)&data->camera, userdata);
+ func(con, (ID**)&data->depth_ob, userdata);
}
static void followtrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *UNUSED(targets))
@@ -3985,7 +3988,6 @@ static void followtrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase
if (data->flag & FOLLOWTRACK_USE_3D_POSITION) {
if (track->flag & TRACK_HAS_BUNDLE) {
- MovieTracking *tracking= &clip->tracking;
float obmat[4][4], mat[4][4];
copy_m4_m4(obmat, cob->matrix);
@@ -4008,9 +4010,8 @@ static void followtrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase
translate_m4(cob->matrix, track->bundle_pos[0], track->bundle_pos[1], track->bundle_pos[2]);
}
}
- }
+ }
else {
- MovieClipUser user;
MovieTrackingMarker *marker;
float vec[3], disp[3], axis[3], mat[4][4];
float aspect= (scene->r.xsch*scene->r.xasp) / (scene->r.ysch*scene->r.yasp);
@@ -4035,8 +4036,7 @@ static void followtrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase
CameraParams params;
float pos[2], rmat[4][4];
- user.framenr= scene->r.cfra;
- marker= BKE_tracking_get_marker(track, user.framenr);
+ marker= BKE_tracking_get_marker(track, scene->r.cfra);
add_v2_v2v2(pos, marker->pos, track->offset);
@@ -4078,6 +4078,34 @@ static void followtrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase
copy_v3_v3(cob->matrix[3], disp);
}
+
+ if(data->depth_ob && data->depth_ob->derivedFinal) {
+ Object *depth_ob= data->depth_ob;
+ BVHTreeFromMesh treeData= NULL_BVHTreeFromMesh;
+ BVHTreeRayHit hit;
+ float ray_start[3], ray_end[3], ray_nor[3], imat[4][4];
+ int result;
+
+ invert_m4_m4(imat, depth_ob->obmat);
+
+ mul_v3_m4v3(ray_start, imat, camob->obmat[3]);
+ mul_v3_m4v3(ray_end, imat, cob->matrix[3]);
+
+ sub_v3_v3v3(ray_nor, ray_end, ray_start);
+
+ bvhtree_from_mesh_faces(&treeData, depth_ob->derivedFinal, 0.0f, 4, 6);
+
+ hit.dist= FLT_MAX;
+ hit.index= -1;
+
+ result= BLI_bvhtree_ray_cast(treeData.tree, ray_start, ray_nor, 0.0f, &hit, treeData.raycast_callback, &treeData);
+
+ if(result != -1) {
+ mul_v3_m4v3(cob->matrix[3], depth_ob->obmat, hit.co);
+ }
+
+ free_bvhtree_from_mesh(&treeData);
+ }
}
}
}
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c
index 3cb2f8ce738..762aaf3efc1 100644
--- a/source/blender/blenkernel/intern/depsgraph.c
+++ b/source/blender/blenkernel/intern/depsgraph.c
@@ -657,6 +657,11 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O
if((data->clip || data->flag&FOLLOWTRACK_ACTIVECLIP) && data->track[0])
depends_on_camera= 1;
+
+ if(data->depth_ob) {
+ node2 = dag_get_node(dag, data->depth_ob);
+ dag_add_relation(dag, node2, node, DAG_RL_DATA_OB|DAG_RL_OB_OB, cti->name);
+ }
}
else if(cti->type==CONSTRAINT_TYPE_OBJECTSOLVER)
depends_on_camera= 1;
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index 408a141608d..ef2249409f0 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -1248,8 +1248,6 @@ void mesh_set_smooth_flag(Object *meshOb, int enableSmooth)
mf->flag &= ~ME_SMOOTH;
}
}
-
- mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL);
}
void mesh_calc_normals(MVert *mverts, int numVerts, MFace *mfaces, int numFaces, float (*faceNors_r)[3])
diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c
index ab963f1e78c..4c78ab13874 100644
--- a/source/blender/blenkernel/intern/movieclip.c
+++ b/source/blender/blenkernel/intern/movieclip.c
@@ -860,7 +860,9 @@ void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClip
undist_marker.pos[1]/= height*aspy;
}
- tmpibuf= BKE_tracking_get_pattern_imbuf(ibuf, track, &undist_marker, 1, 1, scopes->track_pos, NULL);
+ /* NOTE: margin should be kept in sync with value from ui_draw_but_TRACKPREVIEW */
+ tmpibuf= BKE_tracking_get_pattern_imbuf(ibuf, track, &undist_marker, 2 /* margin */,
+ 1 /* anchor */, scopes->track_pos, NULL);
if(tmpibuf->rect_float)
IMB_rect_from_float(tmpibuf);
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index ce1dd429794..5253d7a9961 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -1325,6 +1325,11 @@ void nodeSetActive(bNodeTree *ntree, bNode *node)
node->flag |= NODE_ACTIVE_TEXTURE;
}
+int nodeSocketIsHidden(bNodeSocket *sock)
+{
+ return ((sock->flag & (SOCK_HIDDEN | SOCK_AUTO_HIDDEN | SOCK_UNAVAIL)) != 0);
+}
+
/* ************** dependency stuff *********** */
/* node is guaranteed to be not checked before */
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index ac612e3e996..fab59a7b88a 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -432,7 +432,8 @@ void unlink_object(Object *ob)
if(pchan->custom==ob)
pchan->custom= NULL;
}
- } else if(ELEM(OB_MBALL, ob->type, obt->type)) {
+ }
+ else if(ELEM(OB_MBALL, ob->type, obt->type)) {
if(is_mball_basis_for(obt, ob))
obt->recalc|= OB_RECALC_DATA;
}
@@ -618,21 +619,6 @@ void unlink_object(Object *ob)
sce= sce->id.next;
}
-#if 0 // XXX old animation system
- /* ipos */
- ipo= bmain->ipo.first;
- while(ipo) {
- if(ipo->id.lib==NULL) {
- IpoCurve *icu;
- for(icu= ipo->curve.first; icu; icu= icu->next) {
- if(icu->driver && icu->driver->ob==ob)
- icu->driver->ob= NULL;
- }
- }
- ipo= ipo->id.next;
- }
-#endif // XXX old animation system
-
/* screens */
sc= bmain->screen.first;
while(sc) {
@@ -1000,7 +986,7 @@ void copy_object_particlesystems(Object *obn, Object *ob)
}
else if (md->type==eModifierType_Smoke) {
SmokeModifierData *smd = (SmokeModifierData*) md;
-
+
if(smd->type==MOD_SMOKE_TYPE_FLOW) {
if (smd->flow) {
if (smd->flow->psys == psys)
@@ -1036,22 +1022,6 @@ static void copy_object_pose(Object *obn, Object *ob)
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
-#if 0 // XXX old animation system
- /* note that we can't change lib linked ipo blocks. for making
- * proxies this still works correct however because the object
- * is changed to object->proxy_from when evaluating the driver. */
- if(con->ipo && !con->ipo->id.lib) {
- IpoCurve *icu;
-
- con->ipo= copy_ipo(con->ipo);
-
- for(icu= con->ipo->curve.first; icu; icu= icu->next) {
- if(icu->driver && icu->driver->ob==ob)
- icu->driver->ob= obn;
- }
- }
-#endif // XXX old animation system
-
if (cti && cti->get_constraint_targets) {
cti->get_constraint_targets(con, &targets);
@@ -1081,8 +1051,7 @@ static int object_pose_context(Object *ob)
}
}
-//Object *object_pose_armature_get(Object *ob)
-Object *object_pose_armature_get(struct Object *ob)
+Object *object_pose_armature_get(Object *ob)
{
if(ob==NULL)
return NULL;
@@ -1188,13 +1157,8 @@ Object *copy_object(Object *ob)
static void extern_local_object(Object *ob)
{
- //bActionStrip *strip;
ParticleSystem *psys;
-#if 0 // XXX old animation system
- id_lib_extern((ID *)ob->action);
- id_lib_extern((ID *)ob->ipo);
-#endif // XXX old animation system
id_lib_extern((ID *)ob->data);
id_lib_extern((ID *)ob->dup_group);
id_lib_extern((ID *)ob->poselib);
@@ -1202,11 +1166,6 @@ static void extern_local_object(Object *ob)
extern_local_matarar(ob->mat, ob->totcol);
-#if 0 // XXX old animation system
- for (strip=ob->nlastrips.first; strip; strip=strip->next) {
- id_lib_extern((ID *)strip->act);
- }
-#endif // XXX old animation system
for(psys=ob->particlesystem.first; psys; psys=psys->next)
id_lib_extern((ID *)psys->part);
}
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index e4dcfcf1354..4afe9412786 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -39,6 +39,10 @@
#include <math.h>
#include <string.h>
+#ifdef _OPENMP
+#include <omp.h>
+#endif
+
#include "MEM_guardedalloc.h"
#include "DNA_anim_types.h"
@@ -2301,6 +2305,7 @@ static EdgeHash *sph_springhash_build(ParticleSystem *psys)
return springhash;
}
+#define SPH_NEIGHBORS 512
typedef struct SPHNeighbor
{
ParticleSystem *psys;
@@ -2308,7 +2313,7 @@ typedef struct SPHNeighbor
} SPHNeighbor;
typedef struct SPHRangeData
{
- SPHNeighbor neighbors[128];
+ SPHNeighbor neighbors[SPH_NEIGHBORS];
int tot_neighbors;
float density, near_density;
@@ -2319,10 +2324,6 @@ typedef struct SPHRangeData
float massfac;
int use_size;
-
- /* Same as SPHData::element_size */
- float element_size;
- float flow[3];
} SPHRangeData;
typedef struct SPHData {
ParticleSystem *psys[10];
@@ -2332,9 +2333,15 @@ typedef struct SPHData {
float *gravity;
/* Average distance to neighbours (other particles in the support domain),
for calculating the Courant number (adaptive time step). */
+ int pass;
float element_size;
float flow[3];
+
+ /* Integrator callbacks. This allows different SPH implementations. */
+ void (*force_cb) (void *sphdata_v, ParticleKey *state, float *force, float *impulse);
+ void (*density_cb) (void *rangedata_v, int index, float squared_dist);
}SPHData;
+
static void sph_density_accum_cb(void *userdata, int index, float squared_dist)
{
SPHRangeData *pfr = (SPHRangeData *)userdata;
@@ -2345,11 +2352,13 @@ static void sph_density_accum_cb(void *userdata, int index, float squared_dist)
if(npa == pfr->pa || squared_dist < FLT_EPSILON)
return;
- /* Ugh! One particle has over 128 neighbors! Really shouldn't happen,
- * but even if it does it shouldn't do any terrible harm if all are
- * not taken into account - jahka
+ /* Ugh! One particle has too many neighbors! If some aren't taken into
+ * account, the forces will be biased by the tree search order. This
+ * effectively adds enery to the system, and results in a churning motion.
+ * But, we have to stop somewhere, and it's not the end of the world.
+ * - jahka and z0r
*/
- if(pfr->tot_neighbors >= 128)
+ if(pfr->tot_neighbors >= SPH_NEIGHBORS)
return;
pfr->neighbors[pfr->tot_neighbors].index = index;
@@ -2359,15 +2368,38 @@ static void sph_density_accum_cb(void *userdata, int index, float squared_dist)
dist = sqrtf(squared_dist);
q = (1.f - dist/pfr->h) * pfr->massfac;
- add_v3_v3(pfr->flow, npa->state.vel);
- pfr->element_size += dist;
-
if(pfr->use_size)
q *= npa->size;
pfr->density += q*q;
pfr->near_density += q*q*q;
}
+/*
+ * Find the Courant number for an SPH particle (used for adaptive time step).
+ */
+static void sph_particle_courant(SPHData *sphdata, SPHRangeData *pfr) {
+ ParticleData *pa, *npa;
+ int i;
+ float flow[3], offset[3], dist;
+
+ flow[0] = flow[1] = flow[2] = 0.0f;
+ dist = 0.0f;
+ if (pfr->tot_neighbors > 0) {
+ pa = pfr->pa;
+ for (i=0; i < pfr->tot_neighbors; i++) {
+ npa = pfr->neighbors[i].psys->particles + pfr->neighbors[i].index;
+ sub_v3_v3v3(offset, pa->prev_state.co, npa->prev_state.co);
+ dist += len_v3(offset);
+ add_v3_v3(flow, npa->prev_state.vel);
+ }
+ dist += sphdata->psys[0]->part->fluid->radius; // TODO: remove this? - z0r
+ sphdata->element_size = dist / pfr->tot_neighbors;
+ mul_v3_v3fl(sphdata->flow, flow, 1.0f / pfr->tot_neighbors);
+ } else {
+ sphdata->element_size = MAXFLOAT;
+ VECCOPY(sphdata->flow, flow);
+ }
+}
static void sph_force_cb(void *sphdata_v, ParticleKey *state, float *force, float *UNUSED(impulse))
{
SPHData *sphdata = (SPHData *)sphdata_v;
@@ -2408,24 +2440,14 @@ static void sph_force_cb(void *sphdata_v, ParticleKey *state, float *force, floa
pfr.density = pfr.near_density = 0.f;
pfr.h = h;
pfr.pa = pa;
- pfr.element_size = fluid->radius;
- pfr.flow[0] = pfr.flow[1] = pfr.flow[2] = 0.0f;
for(i=0; i<10 && psys[i]; i++) {
pfr.npsys = psys[i];
pfr.massfac = psys[i]->part->mass*inv_mass;
pfr.use_size = psys[i]->part->flag & PART_SIZEMASS;
- BLI_bvhtree_range_query(psys[i]->bvhtree, state->co, h, sph_density_accum_cb, &pfr);
- }
- if (pfr.tot_neighbors > 0) {
- pfr.element_size /= pfr.tot_neighbors;
- mul_v3_fl(pfr.flow, 1.0f / pfr.tot_neighbors);
- } else {
- pfr.element_size = MAXFLOAT;
+ BLI_bvhtree_range_query(psys[i]->bvhtree, state->co, h, sphdata->density_cb, &pfr);
}
- sphdata->element_size = pfr.element_size;
- copy_v3_v3(sphdata->flow, pfr.flow);
pressure = stiffness * (pfr.density - rest_density);
near_pressure = stiffness_near_fac * pfr.near_density;
@@ -2464,6 +2486,7 @@ static void sph_force_cb(void *sphdata_v, ParticleKey *state, float *force, floa
if(spring_constant > 0.f) {
/* Viscoelastic spring force */
if (pfn->psys == psys[0] && fluid->flag & SPH_VISCOELASTIC_SPRINGS && springhash) {
+ /* BLI_edgehash_lookup appears to be thread-safe. - z0r */
spring_index = GET_INT_FROM_POINTER(BLI_edgehash_lookup(springhash, index, pfn->index));
if(spring_index) {
@@ -2477,7 +2500,9 @@ static void sph_force_cb(void *sphdata_v, ParticleKey *state, float *force, floa
temp_spring.particle_index[1] = pfn->index;
temp_spring.rest_length = (fluid->flag & SPH_CURRENT_REST_LENGTH) ? rij : rest_length;
temp_spring.delete_flag = 0;
-
+
+ /* sph_spring_add is not thread-safe. - z0r */
+ #pragma omp critical
sph_spring_add(psys[0], &temp_spring);
}
}
@@ -2490,29 +2515,52 @@ static void sph_force_cb(void *sphdata_v, ParticleKey *state, float *force, floa
/* Artificial buoyancy force in negative gravity direction */
if (fluid->buoyancy > 0.f && gravity)
madd_v3_v3fl(force, gravity, fluid->buoyancy * (pfr.density-rest_density));
+
+ if (sphdata->pass == 0 && psys[0]->part->time_flag & PART_TIME_AUTOSF)
+ sph_particle_courant(sphdata, &pfr);
+ sphdata->pass++;
}
-static void sph_integrate(ParticleSimulationData *sim, ParticleData *pa, float dfra, float *gravity, EdgeHash *springhash, float *element_size, float flow[3])
-{
+static void sph_solver_init(ParticleSimulationData *sim, SPHData *sphdata) {
ParticleTarget *pt;
int i;
+ // Add other coupled particle systems.
+ sphdata->psys[0] = sim->psys;
+ for(i=1, pt=sim->psys->targets.first; i<10; i++, pt=(pt?pt->next:NULL))
+ sphdata->psys[i] = pt ? psys_get_target_system(sim->ob, pt) : NULL;
+
+ if (psys_uses_gravity(sim))
+ sphdata->gravity = sim->scene->physics_settings.gravity;
+ else
+ sphdata->gravity = NULL;
+ sphdata->eh = sph_springhash_build(sim->psys);
+
+ // These per-particle values should be overridden later, but just for
+ // completeness we give them default values now.
+ sphdata->pa = NULL;
+ sphdata->mass = 1.0f;
+
+ sphdata->force_cb = sph_force_cb;
+ sphdata->density_cb = sph_density_accum_cb;
+}
+static void sph_solver_finalise(SPHData *sphdata) {
+ if (sphdata->eh) {
+ BLI_edgehash_free(sphdata->eh, NULL);
+ sphdata->eh = NULL;
+ }
+}
+static void sph_integrate(ParticleSimulationData *sim, ParticleData *pa, float dfra, SPHData *sphdata){
ParticleSettings *part = sim->psys->part;
// float timestep = psys_get_timestep(sim); // UNUSED
float pa_mass = part->mass * (part->flag & PART_SIZEMASS ? pa->size : 1.f);
float dtime = dfra*psys_get_timestep(sim);
// int steps = 1; // UNUSED
float effector_acceleration[3];
- SPHData sphdata;
- sphdata.psys[0] = sim->psys;
- for(i=1, pt=sim->psys->targets.first; i<10; i++, pt=(pt?pt->next:NULL))
- sphdata.psys[i] = pt ? psys_get_target_system(sim->ob, pt) : NULL;
-
- sphdata.pa = pa;
- sphdata.gravity = gravity;
- sphdata.mass = pa_mass;
- sphdata.eh = springhash;
+ sphdata->pa = pa;
+ sphdata->mass = pa_mass;
+ sphdata->pass = 0;
//sphdata.element_size and sphdata.flow are set in the callback.
/* restore previous state and treat gravity & effectors as external acceleration*/
@@ -2521,9 +2569,7 @@ static void sph_integrate(ParticleSimulationData *sim, ParticleData *pa, float d
copy_particle_key(&pa->state, &pa->prev_state, 0);
- integrate_particle(part, pa, dtime, effector_acceleration, sph_force_cb, &sphdata);
- *element_size = sphdata.element_size;
- copy_v3_v3(flow, sphdata.flow);
+ integrate_particle(part, pa, dtime, effector_acceleration, sphdata->force_cb, sphdata);
}
/************************************************/
@@ -3623,15 +3669,15 @@ static void save_hair(ParticleSimulationData *sim, float UNUSED(cfra))
step, after the velocity has been updated. element_size defines the scale of
the simulation, and is typically the distance to neighbourning particles. */
void update_courant_num(ParticleSimulationData *sim, ParticleData *pa,
- float dtime, float element_size, float flow[3])
+ float dtime, SPHData *sphdata)
{
float relative_vel[3];
float speed;
- sub_v3_v3v3(relative_vel, pa->state.vel, flow);
+ sub_v3_v3v3(relative_vel, pa->prev_state.vel, sphdata->flow);
speed = len_v3(relative_vel);
- if (sim->courant_num < speed * dtime / element_size)
- sim->courant_num = speed * dtime / element_size;
+ if (sim->courant_num < speed * dtime / sphdata->element_size)
+ sim->courant_num = speed * dtime / sphdata->element_size;
}
/* Update time step size to suit current conditions. */
float update_timestep(ParticleSystem *psys, ParticleSimulationData *sim,
@@ -3717,11 +3763,11 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra)
case PART_PHYS_FLUID:
{
ParticleTarget *pt = psys->targets.first;
- psys_update_particle_bvhtree(psys, psys->cfra);
+ psys_update_particle_bvhtree(psys, cfra);
for(; pt; pt=pt->next) { /* Updating others systems particle tree for fluid-fluid interaction */
if(pt->ob)
- psys_update_particle_bvhtree(BLI_findlink(&pt->ob->particlesystem, pt->psys-1), psys->cfra);
+ psys_update_particle_bvhtree(BLI_findlink(&pt->ob->particlesystem, pt->psys-1), cfra);
}
break;
}
@@ -3803,37 +3849,32 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra)
}
case PART_PHYS_FLUID:
{
- EdgeHash *springhash = sph_springhash_build(psys);
- float *gravity = NULL;
- float element_size, flow[3];
-
- if(psys_uses_gravity(sim))
- gravity = sim->scene->physics_settings.gravity;
+ SPHData sphdata;
+ sph_solver_init(sim, &sphdata);
+ #pragma omp parallel for firstprivate (sphdata) private (pa) schedule(dynamic,5)
LOOP_DYNAMIC_PARTICLES {
/* do global forces & effectors */
basic_integrate(sim, p, pa->state.time, cfra);
/* actual fluids calculations */
- sph_integrate(sim, pa, pa->state.time, gravity, springhash,
- &element_size, flow);
+ sph_integrate(sim, pa, pa->state.time, &sphdata);
if(sim->colliders)
collision_check(sim, p, pa->state.time, cfra);
- /* SPH particles are not physical particles, just interpolation particles, thus rotation has not a direct sense for them */
+ /* SPH particles are not physical particles, just interpolation
+ * particles, thus rotation has not a direct sense for them */
basic_rotate(part, pa, pa->state.time, timestep);
+ #pragma omp critical
if (part->time_flag & PART_TIME_AUTOSF)
- update_courant_num(sim, pa, dtime, element_size, flow);
+ update_courant_num(sim, pa, dtime, &sphdata);
}
sph_springs_modify(psys, timestep);
- if(springhash) {
- BLI_edgehash_free(springhash, NULL);
- springhash = NULL;
- }
+ sph_solver_finalise(&sphdata);
break;
}
}
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index 5a57299cf25..7ea4fd751c4 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -80,8 +80,6 @@
#include "FRS_freestyle_config.h"
-//XXX #include "nla.h"
-
#ifdef WIN32
#else
#include <sys/time.h>
diff --git a/source/blender/blenkernel/intern/seqeffects.c b/source/blender/blenkernel/intern/seqeffects.c
index 718b3144677..731f82e1b80 100644
--- a/source/blender/blenkernel/intern/seqeffects.c
+++ b/source/blender/blenkernel/intern/seqeffects.c
@@ -1574,7 +1574,6 @@ typedef struct WipeZone {
int flip;
int xo, yo;
int width;
- float invwidth;
float pythangle;
} WipeZone;
@@ -1585,33 +1584,25 @@ static void precalc_wipe_zone(WipeZone *wipezone, WipeVars *wipe, int xo, int yo
wipezone->xo = xo;
wipezone->yo = yo;
wipezone->width = (int)(wipe->edgeWidth*((xo+yo)/2.0f));
- wipezone->pythangle = 1.0f/sqrtf(wipe->angle*wipe->angle + 1.0f);
-
- if(wipe->wipetype == DO_SINGLE_WIPE)
- wipezone->invwidth = 1.0f/wipezone->width;
- else
- wipezone->invwidth = 1.0f/(0.5f*wipezone->width);
+ wipezone->pythangle = 1.0f/sqrtf(wipezone->angle*wipezone->angle + 1.0f);
}
// This function calculates the blur band for the wipe effects
-static float in_band(WipeZone *wipezone,float width,float dist,float perc,int side,int dir)
+static float in_band(float width,float dist,int side,int dir)
{
- float t1,t2,alpha;
+ float alpha;
if(width == 0)
return (float)side;
-
+
if(width < dist)
- return side;
-
- t1 = dist * wipezone->invwidth; //percentange of width that is
- t2 = wipezone->invwidth; //amount of alpha per % point
-
+ return (float)side;
+
if(side == 1)
- alpha = (t1*t2*100) + (1-perc); // add point's alpha contrib to current position in wipe
+ alpha = (dist+0.5*width) / (width);
else
- alpha = (1-perc) - (t1*t2*100);
-
+ alpha = (0.5*width-dist) / (width);
+
if(dir == 0)
alpha = 1-alpha;
@@ -1648,7 +1639,6 @@ float hyp3,hyp4,b4,b5
switch (wipe->wipetype) {
case DO_SINGLE_WIPE:
width = wipezone->width;
- hwidth = width*0.5f;
if(angle == 0.0f) {
b1 = posy;
@@ -1669,15 +1659,15 @@ float hyp3,hyp4,b4,b5
if(wipe->forward) {
if(b1 < b2)
- output = in_band(wipezone,width,hyp,facf0,1,1);
+ output = in_band(width,hyp,1,1);
else
- output = in_band(wipezone,width,hyp,facf0,0,1);
+ output = in_band(width,hyp,0,1);
}
else {
if(b1 < b2)
- output = in_band(wipezone,width,hyp,facf0,0,1);
+ output = in_band(width,hyp,0,1);
else
- output = in_band(wipezone,width,hyp,facf0,1,1);
+ output = in_band(width,hyp,1,1);
}
break;
@@ -1700,27 +1690,23 @@ float hyp3,hyp4,b4,b5
b3 = (yo-posy*0.5f) - (-angle)*(xo-posx*0.5f);
b2 = y - (-angle)*x;
- hyp = abs(angle*x+y+(-posy*0.5f-angle*posx*0.5f))*wipezone->pythangle;
- hyp2 = abs(angle*x+y+(-(yo-posy*0.5f)-angle*(xo-posx*0.5f)))*wipezone->pythangle;
+ hyp = fabsf(angle*x+y+(-posy*0.5f-angle*posx*0.5f))*wipezone->pythangle;
+ hyp2 = fabsf(angle*x+y+(-(yo-posy*0.5f)-angle*(xo-posx*0.5f)))*wipezone->pythangle;
}
- temp1 = xo*(1-facf0*0.5f)-xo*facf0*0.5f;
- temp2 = yo*(1-facf0*0.5f)-yo*facf0*0.5f;
- pointdist = sqrt(temp1*temp1 + temp2*temp2);
+ hwidth= MIN2(hwidth, fabsf(b3-b1)/2.0f);
if(b2 < b1 && b2 < b3 ){
- if(hwidth < pointdist)
- output = in_band(wipezone,hwidth,hyp,facf0,0,1);
+ output = in_band(hwidth,hyp,0,1);
} else if(b2 > b1 && b2 > b3 ){
- if(hwidth < pointdist)
- output = in_band(wipezone,hwidth,hyp2,facf0,0,1);
+ output = in_band(hwidth,hyp2,0,1);
} else {
if( hyp < hwidth && hyp2 > hwidth )
- output = in_band(wipezone,hwidth,hyp,facf0,1,1);
+ output = in_band(hwidth,hyp,1,1);
else if( hyp > hwidth && hyp2 < hwidth )
- output = in_band(wipezone,hwidth,hyp2,facf0,1,1);
+ output = in_band(hwidth,hyp2,1,1);
else
- output = in_band(wipezone,hwidth,hyp2,facf0,1,1) * in_band(wipezone,hwidth,hyp,facf0,1,1);
+ output = in_band(hwidth,hyp2,1,1) * in_band(hwidth,hyp,1,1);
}
if(!wipe->forward)output = 1-output;
break;
@@ -1840,8 +1826,8 @@ float hyp3,hyp4,b4,b5
pointdist = sqrt(temp1*temp1 + temp1*temp1);
temp2 = sqrt((halfx-x)*(halfx-x) + (halfy-y)*(halfy-y));
- if(temp2 > pointdist) output = in_band(wipezone,hwidth,fabs(temp2-pointdist),facf0,0,1);
- else output = in_band(wipezone,hwidth,fabs(temp2-pointdist),facf0,1,1);
+ if(temp2 > pointdist) output = in_band(hwidth,fabs(temp2-pointdist),0,1);
+ else output = in_band(hwidth,fabs(temp2-pointdist),1,1);
if(!wipe->forward) output = 1-output;
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index cc4b8917a32..6da9199ddc4 100644
--- a/source/blender/blenkernel/intern/sequencer.c
+++ b/source/blender/blenkernel/intern/sequencer.c
@@ -3070,10 +3070,10 @@ void seq_sound_init(Scene *scene, Sequence *seq)
}
else {
if(seq->sound) {
- seq->scene_sound = sound_add_scene_sound(scene, seq, seq->startdisp, seq->enddisp, seq->startofs + seq->anim_startofs);
+ seq->scene_sound = sound_add_scene_sound_defaults(scene, seq);
}
if(seq->scene) {
- sound_scene_add_scene_sound(scene, seq, seq->startdisp, seq->enddisp, seq->startofs + seq->anim_startofs);
+ sound_scene_add_scene_sound_defaults(scene, seq);
}
}
}
@@ -3227,10 +3227,8 @@ void seq_update_sound_bounds_all(Scene *scene)
void seq_update_sound_bounds(Scene* scene, Sequence *seq)
{
- if(seq->scene_sound) {
- sound_move_scene_sound(scene, seq->scene_sound, seq->startdisp, seq->enddisp, seq->startofs + seq->anim_startofs);
- /* mute is set in seq_update_muting_recursive */
- }
+ sound_move_scene_sound_defaults(scene, seq);
+ /* mute is set in seq_update_muting_recursive */
}
static void seq_update_muting_recursive(ListBase *seqbasep, Sequence *metaseq, int mute)
@@ -3772,7 +3770,7 @@ static Sequence *seq_dupli(struct Scene *scene, struct Scene *scene_to, Sequence
} else if(seq->type == SEQ_SCENE) {
seqn->strip->stripdata = NULL;
if(seq->scene_sound)
- seqn->scene_sound = sound_scene_add_scene_sound(sce_audio, seqn, seq->startdisp, seq->enddisp, seq->startofs + seq->anim_startofs);
+ seqn->scene_sound = sound_scene_add_scene_sound_defaults(sce_audio, seqn);
} else if(seq->type == SEQ_MOVIE) {
seqn->strip->stripdata =
MEM_dupallocN(seq->strip->stripdata);
@@ -3781,7 +3779,7 @@ static Sequence *seq_dupli(struct Scene *scene, struct Scene *scene_to, Sequence
seqn->strip->stripdata =
MEM_dupallocN(seq->strip->stripdata);
if(seq->scene_sound)
- seqn->scene_sound = sound_add_scene_sound(sce_audio, seqn, seq->startdisp, seq->enddisp, seq->startofs + seq->anim_startofs);
+ seqn->scene_sound = sound_add_scene_sound_defaults(sce_audio, seqn);
seqn->sound->id.us++;
} else if(seq->type == SEQ_IMAGE) {
diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c
index ceaba2502d9..649984a7934 100644
--- a/source/blender/blenkernel/intern/sound.c
+++ b/source/blender/blenkernel/intern/sound.c
@@ -449,6 +449,13 @@ void* sound_scene_add_scene_sound(struct Scene *scene, struct Sequence* sequence
return NULL;
}
+void* sound_scene_add_scene_sound_defaults(struct Scene *scene, struct Sequence* sequence)
+{
+ return sound_scene_add_scene_sound(scene, sequence,
+ sequence->startdisp, sequence->enddisp,
+ sequence->startofs + sequence->anim_startofs);
+}
+
void* sound_add_scene_sound(struct Scene *scene, struct Sequence* sequence, int startframe, int endframe, int frameskip)
{
void* handle = AUD_addSequence(scene->sound_scene, sequence->sound->playback_handle, startframe / FPS, endframe / FPS, frameskip / FPS);
@@ -459,6 +466,13 @@ void* sound_add_scene_sound(struct Scene *scene, struct Sequence* sequence, int
return handle;
}
+void* sound_add_scene_sound_defaults(struct Scene *scene, struct Sequence* sequence)
+{
+ return sound_add_scene_sound(scene, sequence,
+ sequence->startdisp, sequence->enddisp,
+ sequence->startofs + sequence->anim_startofs);
+}
+
void sound_remove_scene_sound(struct Scene *scene, void* handle)
{
AUD_removeSequence(scene->sound_scene, handle);
@@ -474,6 +488,15 @@ void sound_move_scene_sound(struct Scene *scene, void* handle, int startframe, i
AUD_moveSequence(handle, startframe / FPS, endframe / FPS, frameskip / FPS);
}
+void sound_move_scene_sound_defaults(struct Scene *scene, struct Sequence* sequence)
+{
+ if (sequence->scene_sound) {
+ sound_move_scene_sound(scene, sequence->scene_sound,
+ sequence->startdisp, sequence->enddisp,
+ sequence->startofs + sequence->anim_startofs);
+ }
+}
+
void sound_update_scene_sound(void* handle, struct bSound* sound)
{
AUD_updateSequenceSound(handle, sound->playback_handle);
@@ -781,11 +804,13 @@ void sound_create_scene(struct Scene *UNUSED(scene)) {}
void sound_destroy_scene(struct Scene *UNUSED(scene)) {}
void sound_mute_scene(struct Scene *UNUSED(scene), int UNUSED(muted)) {}
void* sound_scene_add_scene_sound(struct Scene *UNUSED(scene), struct Sequence* UNUSED(sequence), int UNUSED(startframe), int UNUSED(endframe), int UNUSED(frameskip)) { return NULL; }
+void* sound_scene_add_scene_sound_defaults(struct Scene *UNUSED(scene), struct Sequence* UNUSED(sequence)) { return NULL; }
void* sound_add_scene_sound(struct Scene *UNUSED(scene), struct Sequence* UNUSED(sequence), int UNUSED(startframe), int UNUSED(endframe), int UNUSED(frameskip)) { return NULL; }
+void* sound_add_scene_sound_defaults(struct Scene *UNUSED(scene), struct Sequence* UNUSED(sequence)) { return NULL; }
void sound_remove_scene_sound(struct Scene *UNUSED(scene), void* UNUSED(handle)) {}
void sound_mute_scene_sound(void* UNUSED(handle), char UNUSED(mute)) {}
void sound_move_scene_sound(struct Scene *UNUSED(scene), void* UNUSED(handle), int UNUSED(startframe), int UNUSED(endframe), int UNUSED(frameskip)) {}
-static void sound_start_play_scene(struct Scene *UNUSED(scene)) {}
+void sound_move_scene_sound_defaults(struct Scene *UNUSED(scene), struct Sequence *UNUSED(sequence)) {}
void sound_play_scene(struct Scene *UNUSED(scene)) {}
void sound_stop_scene(struct Scene *UNUSED(scene)) {}
void sound_seek_scene(struct Main *UNUSED(bmain), struct Scene *UNUSED(scene)) {}
diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c
index 7bfc7a8ef87..ff76fc14755 100644
--- a/source/blender/blenkernel/intern/tracking.c
+++ b/source/blender/blenkernel/intern/tracking.c
@@ -999,17 +999,24 @@ static ImBuf *get_area_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTracki
if(anchored)
add_v2_v2(mpos, track->offset);
+ if(pos)
+ zero_v2(pos);
+
x= mpos[0]*ibuf->x;
y= mpos[1]*ibuf->y;
- x1= x-(int)(-min[0]*ibuf->x);
- y1= y-(int)(-min[1]*ibuf->y);
- x2= x+(int)(max[0]*ibuf->x);
- y2= y+(int)(max[1]*ibuf->y);
- /* dimensions should be odd */
- w= (x2-x1)|1;
- h= (y2-y1)|1;
+ w= (max[0]-min[0])*ibuf->x;
+ h= (max[1]-min[1])*ibuf->y;
+
+ w= w|1;
+ h= h|1;
+ x1= x-(int)(w/2.0f);
+ y1= y-(int)(h/2.0f);
+ x2= x+(int)(w/2.0f);
+ y2= y+(int)(h/2.0f);
+
+ /* dimensions should be odd */
tmpibuf= IMB_allocImBuf(w+margin*2, h+margin*2, 32, IB_rect);
IMB_rectcpy(tmpibuf, ibuf, 0, 0, x1-margin, y1-margin, w+margin*2, h+margin*2);
@@ -1023,13 +1030,17 @@ static ImBuf *get_area_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTracki
origin[1]= y1-margin;
}
- if ((track->flag & TRACK_PREVIEW_GRAYSCALE) ||
- (track->flag & TRACK_DISABLE_RED) ||
- (track->flag & TRACK_DISABLE_GREEN) ||
- (track->flag & TRACK_DISABLE_BLUE) ) {
+ if((track->flag & TRACK_PREVIEW_GRAYSCALE) ||
+ (track->flag & TRACK_DISABLE_RED) ||
+ (track->flag & TRACK_DISABLE_GREEN) ||
+ (track->flag & TRACK_DISABLE_BLUE))
+ {
disable_imbuf_channels(tmpibuf, track, 1 /* grayscale */);
}
+ tmpibuf->ftype= PNG;
+ IMB_saveiff(tmpibuf, "/tmp/1.png", IB_rect);
+
return tmpibuf;
}
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 3ffd8979b03..029e526c256 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -39,6 +39,7 @@
#include <fcntl.h> // for open
#include <string.h> // for strrchr strncmp strstr
#include <math.h> // for fabs
+#include <stdarg.h> /* for va_start/end */
#ifndef WIN32
#include <unistd.h> // for read close
@@ -250,6 +251,31 @@ static void *read_struct(FileData *fd, BHead *bh, const char *blockname);
static void direct_link_modifiers(FileData *fd, ListBase *lb);
static void convert_tface_mt(FileData *fd, Main *main);
+/* this function ensures that reports are printed,
+ * in the case of libraray linking errors this is important!
+ *
+ * bit kludge but better then doubling up on prints,
+ * we could alternatively have a versions of a report function which foces printing - campbell
+ */
+static void BKE_reportf_wrap(ReportList *reports, ReportType type, const char *format, ...)
+{
+ char fixed_buf[1024]; /* should be long enough */
+
+ va_list args;
+
+ va_start(args, format);
+ vsnprintf(fixed_buf, sizeof(fixed_buf), format, args);
+ va_end(args);
+
+ fixed_buf[sizeof(fixed_buf) - 1] = '\0';
+
+ BKE_report(reports, type, fixed_buf);
+
+ if(G.background==0) {
+ printf("%s\n", fixed_buf);
+ }
+}
+
static OldNewMap *oldnewmap_new(void)
{
OldNewMap *onm= MEM_callocN(sizeof(*onm), "OldNewMap");
@@ -4116,8 +4142,9 @@ static void lib_link_object(FileData *fd, Main *main)
ob= ob->id.next;
}
- if(warn)
+ if(warn) {
BKE_report(fd->reports, RPT_WARNING, "Warning in console");
+ }
}
@@ -4699,8 +4726,9 @@ static void lib_link_scene(FileData *fd, Main *main)
base->object= newlibadr_us(fd, sce->id.lib, base->object);
if(base->object==NULL) {
- BKE_reportf(fd->reports, RPT_ERROR, "LIB ERROR: Object lost from scene:'%s\'\n", sce->id.name+2);
- if(G.background==0) printf("LIB ERROR: base removed from scene:'%s\'\n", sce->id.name+2);
+ BKE_reportf_wrap(fd->reports, RPT_ERROR,
+ "LIB ERROR: Object lost from scene:'%s\'\n",
+ sce->id.name+2);
BLI_remlink(&sce->base, base);
if(base==sce->basact) sce->basact= NULL;
MEM_freeN(base);
@@ -4713,7 +4741,7 @@ static void lib_link_scene(FileData *fd, Main *main)
if(seq->scene) {
seq->scene= newlibadr(fd, sce->id.lib, seq->scene);
if(seq->scene) {
- seq->scene_sound = sound_scene_add_scene_sound(sce, seq, seq->startdisp, seq->enddisp, seq->startofs + seq->anim_startofs);
+ seq->scene_sound = sound_scene_add_scene_sound_defaults(sce, seq);
}
}
if(seq->scene_camera) seq->scene_camera= newlibadr(fd, sce->id.lib, seq->scene_camera);
@@ -4725,7 +4753,7 @@ static void lib_link_scene(FileData *fd, Main *main)
seq->sound= newlibadr(fd, sce->id.lib, seq->sound);
if (seq->sound) {
seq->sound->id.us++;
- seq->scene_sound = sound_add_scene_sound(sce, seq, seq->startdisp, seq->enddisp, seq->startofs + seq->anim_startofs);
+ seq->scene_sound = sound_add_scene_sound_defaults(sce, seq);
}
}
seq->anim= NULL;
@@ -5812,8 +5840,9 @@ static void direct_link_library(FileData *fd, Library *lib, Main *main)
for(newmain= fd->mainlist.first; newmain; newmain= newmain->next) {
if(newmain->curlib) {
if(BLI_path_cmp(newmain->curlib->filepath, lib->filepath) == 0) {
- printf("Fixed error in file; multiple instances of lib:\n %s\n", lib->filepath);
- BKE_reportf(fd->reports, RPT_WARNING, "Library '%s', '%s' had multiple instances, save and reload!", lib->name, lib->filepath);
+ BKE_reportf_wrap(fd->reports, RPT_WARNING,
+ "Library '%s', '%s' had multiple instances, save and reload!",
+ lib->name, lib->filepath);
change_idid_adr(&fd->mainlist, fd, lib, newmain->curlib);
// change_idid_adr_fd(fd, lib, newmain->curlib);
@@ -7707,6 +7736,32 @@ static void do_versions_nodetree_socket_use_flags_2_62(bNodeTree *ntree)
}
}
+/* set the SOCK_AUTO_HIDDEN flag on collapsed nodes */
+static void do_versions_nodetree_socket_auto_hidden_flags_2_62(bNodeTree *ntree)
+{
+ bNode *node;
+ bNodeSocket *sock;
+
+ for (node=ntree->nodes.first; node; node=node->next) {
+ if (node->flag & NODE_HIDDEN) {
+ for (sock=node->inputs.first; sock; sock=sock->next) {
+ if (sock->link==NULL)
+ sock->flag |= SOCK_AUTO_HIDDEN;
+ }
+ for(sock=node->outputs.first; sock; sock= sock->next) {
+ if(nodeCountSocketLinks(ntree, sock)==0)
+ sock->flag |= SOCK_AUTO_HIDDEN;
+ }
+ }
+ else {
+ for(sock=node->inputs.first; sock; sock= sock->next)
+ sock->flag &= ~SOCK_AUTO_HIDDEN;
+ for(sock=node->outputs.first; sock; sock= sock->next)
+ sock->flag &= ~SOCK_AUTO_HIDDEN;
+ }
+ }
+}
+
static void do_versions(FileData *fd, Library *lib, Main *main)
{
/* WATCH IT!!!: pointers from libdata have not been converted */
@@ -12939,7 +12994,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
}
}
- /* put compatibility code here until next subversion bump */
+ if (main->versionfile < 261 || (main->versionfile == 261 && main->subversionfile < 1))
{
{
/* update use flags for node sockets (was only temporary before) */
@@ -13022,6 +13077,60 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
}
}
}
+ {
+ /* Warn the user if he is using ["Text"] properties for Font objects */
+ Object *ob;
+ bProperty *prop;
+
+ for (ob= main->object.first; ob; ob= ob->id.next) {
+ if (ob->type == OB_FONT) {
+ prop = get_ob_property(ob, "Text");
+ if (prop) {
+ BKE_reportf_wrap(fd->reports, RPT_WARNING,
+ "Game property name conflict in object: \"%s\".\nText objects reserve the "
+ "[\"Text\"] game property to change their content through Logic Bricks.\n",
+ ob->id.name+2);
+ }
+ }
+ }
+ }
+ {
+ /* set the SOCK_AUTO_HIDDEN flag on collapsed nodes */
+ Scene *sce;
+ Material *mat;
+ Tex *tex;
+ Lamp *lamp;
+ World *world;
+ bNodeTree *ntree;
+
+ for (sce=main->scene.first; sce; sce=sce->id.next)
+ if (sce->nodetree)
+ do_versions_nodetree_socket_auto_hidden_flags_2_62(sce->nodetree);
+
+ for (mat=main->mat.first; mat; mat=mat->id.next)
+ if (mat->nodetree)
+ do_versions_nodetree_socket_auto_hidden_flags_2_62(mat->nodetree);
+
+ for (tex=main->tex.first; tex; tex=tex->id.next)
+ if (tex->nodetree)
+ do_versions_nodetree_socket_auto_hidden_flags_2_62(tex->nodetree);
+
+ for (lamp=main->lamp.first; lamp; lamp=lamp->id.next)
+ if (lamp->nodetree)
+ do_versions_nodetree_socket_auto_hidden_flags_2_62(lamp->nodetree);
+
+ for (world=main->world.first; world; world=world->id.next)
+ if (world->nodetree)
+ do_versions_nodetree_socket_auto_hidden_flags_2_62(world->nodetree);
+
+ for (ntree=main->nodetree.first; ntree; ntree=ntree->id.next)
+ do_versions_nodetree_socket_auto_hidden_flags_2_62(ntree);
+ }
+ }
+
+ /* put compatibility code here until next subversion bump */
+ {
+
}
/* default values in Freestyle settings */
@@ -14527,8 +14636,9 @@ static void read_libraries(FileData *basefd, ListBase *mainlist)
if(fd==NULL) {
/* printf and reports for now... its important users know this */
- BKE_reportf(basefd->reports, RPT_INFO, "read library: '%s', '%s'\n", mainptr->curlib->filepath, mainptr->curlib->name);
- if(!G.background && basefd->reports) printf("read library: '%s', '%s'\n", mainptr->curlib->filepath, mainptr->curlib->name);
+ BKE_reportf_wrap(basefd->reports, RPT_INFO,
+ "read library: '%s', '%s'\n",
+ mainptr->curlib->filepath, mainptr->curlib->name);
fd= blo_openblenderfile(mainptr->curlib->filepath, basefd->reports);
@@ -14573,8 +14683,9 @@ static void read_libraries(FileData *basefd, ListBase *mainlist)
else mainptr->curlib->filedata= NULL;
if (fd==NULL) {
- BKE_reportf(basefd->reports, RPT_ERROR, "Can't find lib '%s'\n", mainptr->curlib->filepath);
- if(!G.background && basefd->reports) printf("ERROR: can't find lib %s \n", mainptr->curlib->filepath);
+ BKE_reportf_wrap(basefd->reports, RPT_ERROR,
+ "Can't find lib '%s'\n",
+ mainptr->curlib->filepath);
}
}
if(fd) {
@@ -14591,8 +14702,10 @@ static void read_libraries(FileData *basefd, ListBase *mainlist)
append_id_part(fd, mainptr, id, &realid);
if (!realid) {
- BKE_reportf(fd->reports, RPT_ERROR, "LIB ERROR: %s:'%s' missing from '%s'\n", BKE_idcode_to_name(GS(id->name)), id->name+2, mainptr->curlib->filepath);
- if(!G.background && basefd->reports) printf("LIB ERROR: %s:'%s' missing from '%s'\n", BKE_idcode_to_name(GS(id->name)), id->name+2, mainptr->curlib->filepath);
+ BKE_reportf_wrap(fd->reports, RPT_ERROR,
+ "LIB ERROR: %s:'%s' missing from '%s'\n",
+ BKE_idcode_to_name(GS(id->name)),
+ id->name+2, mainptr->curlib->filepath);
}
change_idid_adr(mainlist, basefd, id, realid);
@@ -14628,13 +14741,9 @@ static void read_libraries(FileData *basefd, ListBase *mainlist)
ID *idn= id->next;
if(id->flag & LIB_READ) {
BLI_remlink(lbarray[a], id);
- BKE_reportf(basefd->reports, RPT_ERROR,
- "LIB ERROR: %s:'%s' unread libblock missing from '%s'\n",
- BKE_idcode_to_name(GS(id->name)), id->name+2, mainptr->curlib->filepath);
- if (!G.background && basefd->reports) {
- printf("LIB ERROR: %s:'%s' unread libblock missing from '%s'\n",
- BKE_idcode_to_name(GS(id->name)), id->name+2, mainptr->curlib->filepath);
- }
+ BKE_reportf_wrap(basefd->reports, RPT_ERROR,
+ "LIB ERROR: %s:'%s' unread libblock missing from '%s'\n",
+ BKE_idcode_to_name(GS(id->name)), id->name+2, mainptr->curlib->filepath);
change_idid_adr(mainlist, basefd, id, NULL);
MEM_freeN(id);
diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c
index beecbc7abed..f1dfbd40c11 100644
--- a/source/blender/editors/animation/anim_filter.c
+++ b/source/blender/editors/animation/anim_filter.c
@@ -1914,6 +1914,10 @@ static size_t animdata_filter_ds_world (bAnimContext *ac, ListBase *anim_data, b
/* textures for world */
if (!(ads->filterflag & ADS_FILTER_NOTEX))
items += animdata_filter_ds_textures(ac, &tmp_data, ads, (ID *)wo, filter_mode);
+
+ /* nodes */
+ if ((wo->nodetree) && !(ads->filterflag & ADS_FILTER_NONTREE))
+ tmp_items += animdata_filter_ds_nodetree(ac, &tmp_data, ads, (ID *)wo, wo->nodetree, filter_mode);
}
END_ANIMFILTER_SUBCHANNELS;
@@ -2009,12 +2013,12 @@ static size_t animdata_filter_dopesheet_scene (bAnimContext *ac, ListBase *anim_
}
/* world */
- if ((wo && wo->adt) && !(ads->filterflag & ADS_FILTER_NOWOR)) {
+ if ((wo) && !(ads->filterflag & ADS_FILTER_NOWOR)) {
tmp_items += animdata_filter_ds_world(ac, &tmp_data, ads, sce, wo, filter_mode);
}
/* nodetree */
- if ((ntree && ntree->adt) && !(ads->filterflag & ADS_FILTER_NONTREE)) {
+ if ((ntree) && !(ads->filterflag & ADS_FILTER_NONTREE)) {
tmp_items += animdata_filter_ds_nodetree(ac, &tmp_data, ads, (ID *)sce, ntree, filter_mode);
}
diff --git a/source/blender/editors/animation/anim_ipo_utils.c b/source/blender/editors/animation/anim_ipo_utils.c
index 8e36e02bbb4..8c4e0065a19 100644
--- a/source/blender/editors/animation/anim_ipo_utils.c
+++ b/source/blender/editors/animation/anim_ipo_utils.c
@@ -161,6 +161,11 @@ int getname_anim_fcurve(char *name, ID *id, FCurve *fcu)
* use the struct's icon if it is set
*/
icon= RNA_struct_ui_icon(ptr.type);
+
+ /* valid path - remove the invalid tag since we now know how to use it saving
+ * users manual effort to reenable using "Revive Disabled FCurves" [#29629]
+ */
+ fcu->flag &= ~FCURVE_DISABLED;
}
else {
/* invalid path */
diff --git a/source/blender/editors/armature/editarmature.c b/source/blender/editors/armature/editarmature.c
index 48f3f78b849..becc7e9b68f 100644
--- a/source/blender/editors/armature/editarmature.c
+++ b/source/blender/editors/armature/editarmature.c
@@ -5067,7 +5067,6 @@ static int pose_de_select_all_exec(bContext *C, wmOperator *op)
{
int action = RNA_enum_get(op->ptr, "action");
- Object *ob = NULL;
Scene *scene= CTX_data_scene(C);
int multipaint = scene->toolsettings->multipaint;
@@ -5100,8 +5099,8 @@ static int pose_de_select_all_exec(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, NULL);
- if(multipaint) {
- ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ if (multipaint) {
+ Object *ob = ED_object_context(C);
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
}
diff --git a/source/blender/editors/armature/poselib.c b/source/blender/editors/armature/poselib.c
index 064defb1aef..5cdb9c76396 100644
--- a/source/blender/editors/armature/poselib.c
+++ b/source/blender/editors/armature/poselib.c
@@ -77,6 +77,7 @@
#include "ED_keyframing.h"
#include "ED_keyframes_edit.h"
#include "ED_screen.h"
+#include "ED_object.h"
#include "armature_intern.h"
@@ -171,7 +172,7 @@ static Object *get_poselib_object (bContext *C)
sa = CTX_wm_area(C);
if (sa && (sa->spacetype == SPACE_BUTS))
- return CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ return ED_object_context(C);
else
return object_pose_armature_get(CTX_data_active_object(C));
}
diff --git a/source/blender/editors/armature/poseobject.c b/source/blender/editors/armature/poseobject.c
index 8d35122650f..832ee55997b 100644
--- a/source/blender/editors/armature/poseobject.c
+++ b/source/blender/editors/armature/poseobject.c
@@ -73,6 +73,7 @@
#include "ED_keyframing.h"
#include "ED_mesh.h"
#include "ED_screen.h"
+#include "ED_object.h"
#include "UI_interface.h"
#include "UI_resources.h"
@@ -207,7 +208,7 @@ static int pose_calculate_paths_exec (bContext *C, wmOperator *op)
/* since this call may also be used from the buttons window, we need to check for where to get the object */
if (sa->spacetype == SPACE_BUTS)
- ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ ob= ED_object_context(C);
else
ob= object_pose_armature_get(CTX_data_active_object(C));
@@ -283,7 +284,7 @@ static int pose_clear_paths_exec (bContext *C, wmOperator *UNUSED(op))
/* since this call may also be used from the buttons window, we need to check for where to get the object */
if (sa->spacetype == SPACE_BUTS)
- ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ ob= ED_object_context(C);
else
ob= object_pose_armature_get(CTX_data_active_object(C));
@@ -1221,7 +1222,7 @@ static int pose_group_add_exec (bContext *C, wmOperator *UNUSED(op))
/* since this call may also be used from the buttons window, we need to check for where to get the object */
if (sa->spacetype == SPACE_BUTS)
- ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ ob= ED_object_context(C);
else
ob= object_pose_armature_get(CTX_data_active_object(C));
@@ -1261,7 +1262,7 @@ static int pose_group_remove_exec (bContext *C, wmOperator *UNUSED(op))
/* since this call may also be used from the buttons window, we need to check for where to get the object */
if (sa->spacetype == SPACE_BUTS)
- ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ ob= ED_object_context(C);
else
ob= object_pose_armature_get(CTX_data_active_object(C));
@@ -1309,7 +1310,7 @@ static int pose_groups_menu_invoke (bContext *C, wmOperator *op, wmEvent *UNUSED
/* since this call may also be used from the buttons window, we need to check for where to get the object */
if (sa->spacetype == SPACE_BUTS)
- ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ ob= ED_object_context(C);
else
ob= object_pose_armature_get(CTX_data_active_object(C));
@@ -1358,7 +1359,7 @@ static int pose_group_assign_exec (bContext *C, wmOperator *op)
/* since this call may also be used from the buttons window, we need to check for where to get the object */
if (sa->spacetype == SPACE_BUTS)
- ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ ob= ED_object_context(C);
else
ob= object_pose_armature_get(CTX_data_active_object(C));
@@ -1421,7 +1422,7 @@ static int pose_group_unassign_exec (bContext *C, wmOperator *UNUSED(op))
/* since this call may also be used from the buttons window, we need to check for where to get the object */
if (sa->spacetype == SPACE_BUTS)
- ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ ob= ED_object_context(C);
else
ob= object_pose_armature_get(CTX_data_active_object(C));
@@ -1466,7 +1467,7 @@ void POSE_OT_group_unassign (wmOperatorType *ot)
static int group_move_exec(bContext *C, wmOperator *op)
{
- Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ Object *ob = ED_object_context(C);
bPose *pose= (ob) ? ob->pose : NULL;
bPoseChannel *pchan;
bActionGroup *grp;
@@ -1564,7 +1565,7 @@ static int compare_agroup(const void *sgrp_a_ptr, const void *sgrp_b_ptr)
static int group_sort_exec(bContext *C, wmOperator *UNUSED(op))
{
- Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ Object *ob = ED_object_context(C);
bPose *pose= (ob) ? ob->pose : NULL;
bPoseChannel *pchan;
tSortActionGroup *agrp_array;
@@ -1656,7 +1657,7 @@ static int pose_group_select_exec (bContext *C, wmOperator *UNUSED(op))
/* since this call may also be used from the buttons window, we need to check for where to get the object */
if (sa->spacetype == SPACE_BUTS)
- ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ ob= ED_object_context(C);
else
ob= object_pose_armature_get(CTX_data_active_object(C));
@@ -1694,7 +1695,7 @@ static int pose_group_deselect_exec (bContext *C, wmOperator *UNUSED(op))
/* since this call may also be used from the buttons window, we need to check for where to get the object */
if (sa->spacetype == SPACE_BUTS)
- ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ ob= ED_object_context(C);
else
ob= object_pose_armature_get(CTX_data_active_object(C));
diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h
index 5c7d9249c5f..51d3c3f021b 100644
--- a/source/blender/editors/include/ED_object.h
+++ b/source/blender/editors/include/ED_object.h
@@ -56,7 +56,8 @@ struct wmOperator;
struct wmOperatorType;
/* object_edit.c */
-struct Object *ED_object_active_context(struct bContext *C);
+struct Object *ED_object_context(struct bContext *C); /* context.object */
+struct Object *ED_object_active_context(struct bContext *C); /* context.object or context.active_object */
/* object_ops.c */
void ED_operatortypes_object(void);
diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c
index 6ebb67af67a..1f1228a9bc5 100644
--- a/source/blender/editors/interface/interface_draw.c
+++ b/source/blender/editors/interface/interface_draw.c
@@ -1465,21 +1465,16 @@ static ImBuf *scale_trackpreview_ibuf(ImBuf *ibuf, float zoomx, float zoomy)
{
ImBuf *scaleibuf;
int x, y, w= ibuf->x*zoomx, h= ibuf->y*zoomy;
- const float max_x= ibuf->x-1.0f;
- const float max_y= ibuf->y-1.0f;
const float scalex= 1.0f/zoomx;
const float scaley= 1.0f/zoomy;
scaleibuf= IMB_allocImBuf(w, h, 32, IB_rect);
- for(y= 0; y<scaleibuf->y; y++) {
- for (x= 0; x<scaleibuf->x; x++) {
+ for(y= 0; y<h; y++) {
+ for (x= 0; x<w; x++) {
float src_x= scalex*x;
float src_y= scaley*y;
- CLAMP(src_x, 0, max_x);
- CLAMP(src_y, 0, max_y);
-
bicubic_interpolation(ibuf, scaleibuf, src_x, src_y, x, y);
}
}
@@ -1514,28 +1509,36 @@ void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wc
ok= 1;
}
else if(scopes->track_preview) {
- int a, off_x, off_y;
- float zoomx, zoomy;
+ /* additional margin around image */
+ /* NOTE: should be kept in sync with value from BKE_movieclip_update_scopes */
+ const int margin= 2;
+ float zoomx, zoomy, track_pos[2], off_x, off_y;
+ int a;
ImBuf *drawibuf;
glPushMatrix();
+ track_pos[0]= scopes->track_pos[0]-margin;
+ track_pos[1]= scopes->track_pos[1]-margin;
+
/* draw content of pattern area */
glScissor(ar->winrct.xmin+rect.xmin, ar->winrct.ymin+rect.ymin, scissor[2], scissor[3]);
- zoomx= (rect.xmax-rect.xmin) / (scopes->track_preview->x-2.0f);
- zoomy= (rect.ymax-rect.ymin) / (scopes->track_preview->y-2.0f);
+ zoomx= (rect.xmax-rect.xmin) / (scopes->track_preview->x-2*margin);
+ zoomy= (rect.ymax-rect.ymin) / (scopes->track_preview->y-2*margin);
- off_x= ((int)scopes->track_pos[0]-scopes->track_pos[0]-0.5f)*zoomx;
- off_y= ((int)scopes->track_pos[1]-scopes->track_pos[1]-0.5f)*zoomy;
+ off_x= ((int)track_pos[0]-track_pos[0]+0.5)*zoomx;
+ off_y= ((int)track_pos[1]-track_pos[1]+0.5)*zoomy;
drawibuf= scale_trackpreview_ibuf(scopes->track_preview, zoomx, zoomy);
- glaDrawPixelsSafe(off_x+rect.xmin, off_y+rect.ymin, rect.xmax-rect.xmin+1.f-off_x, rect.ymax-rect.ymin+1.f-off_y, drawibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, drawibuf->rect);
-
+ glaDrawPixelsSafe(off_x+rect.xmin-zoomx*(margin-0.5f), off_y+rect.ymin-zoomy*(margin-0.5f),
+ rect.xmax-rect.xmin+2+(int)(zoomx*(margin-0.5f)-off_x),
+ rect.ymax-rect.ymin+2+(int)(zoomy*(margin-0.5f)-off_y),
+ drawibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, drawibuf->rect);
IMB_freeImBuf(drawibuf);
/* draw cross for pizel position */
- glTranslatef(off_x+rect.xmin+scopes->track_pos[0]*zoomx, off_y+rect.ymin+scopes->track_pos[1]*zoomy, 0.f);
+ glTranslatef(off_x+rect.xmin+track_pos[0]*zoomx, off_y+rect.ymin+track_pos[1]*zoomy, 0.f);
glScissor(ar->winrct.xmin + rect.xmin, ar->winrct.ymin+rect.ymin, rect.xmax-rect.xmin, rect.ymax-rect.ymin);
for(a= 0; a< 2; a++) {
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index 900cbbd5cbf..525b15ac7e3 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -114,6 +114,17 @@ typedef enum uiButtonJumpType {
BUTTON_EDIT_JUMP_ALL
} uiButtonJumpType;
+typedef enum uiButtonDelimType {
+ BUTTON_DELIM_NONE,
+ BUTTON_DELIM_ALPHA,
+ BUTTON_DELIM_PUNCT,
+ BUTTON_DELIM_BRACE,
+ BUTTON_DELIM_OPERATOR,
+ BUTTON_DELIM_QUOTE,
+ BUTTON_DELIM_WHITESPACE,
+ BUTTON_DELIM_OTHER
+} uiButtonDelimType;
+
typedef struct uiHandleButtonData {
wmWindowManager *wm;
wmWindow *window;
@@ -1230,46 +1241,60 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data,
/* ************* in-button text selection/editing ************* */
/* return 1 if char ch is special character, otherwise return 0 */
-static short test_special_char(char ch)
+static uiButtonDelimType test_special_char(const char ch)
{
+ if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) {
+ return BUTTON_DELIM_ALPHA;
+ }
+
switch(ch) {
- case '\\':
- case '/':
+ case ',':
+ case '.':
+ return BUTTON_DELIM_PUNCT;
+
+ case '{':
+ case '}':
+ case '[':
+ case ']':
+ case '(':
+ case ')':
+ return BUTTON_DELIM_BRACE;
+
+ case '+':
+ case '-':
+ case '=':
case '~':
+ case '%':
+ case '/':
+ case '<':
+ case '>':
+ case '^':
+ case '*':
+ case '&':
+ return BUTTON_DELIM_OPERATOR;
+
+ case '\'':
+ case '\"': // " - an extra closing one for Aligorith's text editor
+ return BUTTON_DELIM_QUOTE;
+
+ case ' ':
+ return BUTTON_DELIM_WHITESPACE;
+
+ case '\\':
case '!':
case '@':
case '#':
case '$':
- case '%':
- case '^':
- case '&':
- case '*':
- case '(':
- case ')':
- case '+':
- case '=':
- case '{':
- case '}':
- case '[':
- case ']':
case ':':
case ';':
- case '\'':
- case '\"': // " - an extra closing one for Aligorith's text editor
- case '<':
- case '>':
- case ',':
- case '.':
case '?':
case '_':
- case '-':
- case ' ':
- return 1;
- break;
+ return BUTTON_DELIM_OTHER;
+
default:
break;
}
- return 0;
+ return BUTTON_DELIM_NONE;
}
static int ui_textedit_step_next_utf8(const char *str, size_t maxlen, short *pos)
@@ -1308,12 +1333,13 @@ static void ui_textedit_step_utf8(const char *str, size_t maxlen,
if(direction) { /* right*/
if(jump != BUTTON_EDIT_JUMP_NONE) {
+ const uiButtonDelimType is_special= (*pos) < maxlen ? test_special_char(str[(*pos)]) : BUTTON_DELIM_NONE;
/* jump between special characters (/,\,_,-, etc.),
* look at function test_special_char() for complete
* list of special character, ctr -> */
while((*pos) < maxlen) {
if (ui_textedit_step_next_utf8(str, maxlen, pos)) {
- if((jump != BUTTON_EDIT_JUMP_ALL) && test_special_char(str[(*pos)])) break;
+ if((jump != BUTTON_EDIT_JUMP_ALL) && (is_special != test_special_char(str[(*pos)]))) break;
}
else {
break; /* unlikely but just incase */
@@ -1326,6 +1352,7 @@ static void ui_textedit_step_utf8(const char *str, size_t maxlen,
}
else { /* left */
if(jump != BUTTON_EDIT_JUMP_NONE) {
+ const uiButtonDelimType is_special= (*pos) > 1 ? test_special_char(str[(*pos) - 1]) : BUTTON_DELIM_NONE;
/* left only: compensate for index/change in direction */
ui_textedit_step_prev_utf8(str, maxlen, pos);
@@ -1334,7 +1361,7 @@ static void ui_textedit_step_utf8(const char *str, size_t maxlen,
* list of special character, ctr -> */
while ((*pos) > 0) {
if (ui_textedit_step_prev_utf8(str, maxlen, pos)) {
- if((jump != BUTTON_EDIT_JUMP_ALL) && test_special_char(str[(*pos)])) break;
+ if((jump != BUTTON_EDIT_JUMP_ALL) && (is_special != test_special_char(str[(*pos)]))) break;
}
else {
break;
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index 0670692a084..8df43b92760 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -55,6 +55,7 @@
#include "BKE_texture.h"
#include "BKE_report.h"
#include "BKE_displist.h"
+#include "BKE_scene.h"
#include "ED_screen.h"
#include "ED_object.h"
@@ -2126,6 +2127,7 @@ static void list_item_row(bContext *C, uiLayout *layout, PointerRNA *ptr, Pointe
else if(RNA_struct_is_a(itemptr->type, &RNA_MaterialSlot)) {
/* provision to draw active node name */
Material *ma, *manode;
+ Scene *scene= CTX_data_scene(C);
Object *ob= (Object*)ptr->id.data;
int index= (Material**)itemptr->data - ob->mat;
@@ -2133,7 +2135,7 @@ static void list_item_row(bContext *C, uiLayout *layout, PointerRNA *ptr, Pointe
uiItemL(sub, name, icon);
ma= give_current_material(ob, index+1);
- if(ma) {
+ if (ma && !scene_use_new_shading_nodes(scene)){
manode= give_node_material(ma);
if(manode) {
char str[MAX_ID_NAME + 12];
diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c
index 5706da93fe9..a993e651b5f 100644
--- a/source/blender/editors/interface/view2d_ops.c
+++ b/source/blender/editors/interface/view2d_ops.c
@@ -248,20 +248,19 @@ static int view_pan_modal(bContext *C, wmOperator *op, wmEvent *event)
view_pan_apply(op);
}
break;
-
+ /* XXX - Mode switching isn't implemented. See comments in 36818.
+ * switch to zoom *
case LEFTMOUSE:
- /* switch to zoom */
if (event->val==KM_PRESS) {
- /* calculate overall delta mouse-movement for redo */
+ * calculate overall delta mouse-movement for redo *
RNA_int_set(op->ptr, "deltax", (vpd->startx - vpd->lastx));
RNA_int_set(op->ptr, "deltay", (vpd->starty - vpd->lasty));
view_pan_exit(op);
WM_cursor_restore(CTX_wm_window(C));
-
WM_operator_name_call(C, "VIEW2D_OT_zoom", WM_OP_INVOKE_DEFAULT, NULL);
return OPERATOR_FINISHED;
- }
+ }*/
default:
if (event->type == vpd->invoke_event || event->type==ESCKEY) {
diff --git a/source/blender/editors/mesh/mesh_data.c b/source/blender/editors/mesh/mesh_data.c
index 7253d426ca6..7762203c371 100644
--- a/source/blender/editors/mesh/mesh_data.c
+++ b/source/blender/editors/mesh/mesh_data.c
@@ -318,14 +318,14 @@ int ED_mesh_color_remove_named(bContext *C, Object *ob, Mesh *me, const char *na
static int layers_poll(bContext *C)
{
- Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ Object *ob= ED_object_context(C);
ID *data= (ob)? ob->data: NULL;
return (ob && !ob->id.lib && ob->type==OB_MESH && data && !data->lib);
}
static int uv_texture_add_exec(bContext *C, wmOperator *UNUSED(op))
{
- Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ Object *ob= ED_object_context(C);
Mesh *me= ob->data;
if(!ED_mesh_uv_texture_add(C, me, NULL, TRUE))
@@ -435,7 +435,7 @@ void MESH_OT_drop_named_image(wmOperatorType *ot)
static int uv_texture_remove_exec(bContext *C, wmOperator *UNUSED(op))
{
- Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ Object *ob= ED_object_context(C);
Mesh *me= ob->data;
if(!ED_mesh_uv_texture_remove(C, ob, me))
@@ -464,7 +464,7 @@ void MESH_OT_uv_texture_remove(wmOperatorType *ot)
static int vertex_color_add_exec(bContext *C, wmOperator *UNUSED(op))
{
Scene *scene= CTX_data_scene(C);
- Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ Object *ob= ED_object_context(C);
Mesh *me= ob->data;
if(!ED_mesh_color_add(C, scene, ob, me, NULL, TRUE))
@@ -490,7 +490,7 @@ void MESH_OT_vertex_color_add(wmOperatorType *ot)
static int vertex_color_remove_exec(bContext *C, wmOperator *UNUSED(op))
{
- Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ Object *ob= ED_object_context(C);
Mesh *me= ob->data;
if(!ED_mesh_color_remove(C, ob, me))
@@ -520,7 +520,7 @@ static int sticky_add_exec(bContext *C, wmOperator *UNUSED(op))
{
Scene *scene= CTX_data_scene(C);
View3D *v3d= CTX_wm_view3d(C);
- Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ Object *ob= ED_object_context(C);
Mesh *me= ob->data;
/*if(me->msticky)
@@ -551,7 +551,7 @@ void MESH_OT_sticky_add(wmOperatorType *ot)
static int sticky_remove_exec(bContext *C, wmOperator *UNUSED(op))
{
- Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ Object *ob= ED_object_context(C);
Mesh *me= ob->data;
if(!me->msticky)
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c
index fa308624454..6a68a264a28 100644
--- a/source/blender/editors/object/object_edit.c
+++ b/source/blender/editors/object/object_edit.c
@@ -108,9 +108,12 @@ static void waitcursor(int UNUSED(val)) {}
static int pupmenu(const char *UNUSED(msg)) {return 0;}
/* port over here */
-static bContext *evil_C;
static void error_libdata(void) {}
+Object *ED_object_context(bContext *C)
+{
+ return CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+}
/* find the correct active object per context
* note: context can be NULL when called from a enum with PROP_ENUM_NO_CONTEXT */
@@ -118,7 +121,7 @@ Object *ED_object_active_context(bContext *C)
{
Object *ob= NULL;
if(C) {
- ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ ob= ED_object_context(C);
if (!ob) ob= CTX_data_active_object(C);
}
return ob;
@@ -718,240 +721,6 @@ static void spot_interactive(Object *ob, int mode)
}
#endif
-static void UNUSED_FUNCTION(special_editmenu)(Scene *scene, View3D *v3d)
-{
-// XXX static short numcuts= 2;
- Object *ob= OBACT;
- Object *obedit= NULL; // XXX
- int nr,ret=0;
-
- if(ob==NULL) return;
-
- if(obedit==NULL) {
-
- if(ob->mode & OB_MODE_POSE) {
-// XXX pose_special_editmenu();
- }
- else if(paint_facesel_test(ob)) {
- Mesh *me= get_mesh(ob);
- MTFace *tface;
- MFace *mface;
- int a;
-
- if(me==NULL || me->mtface==NULL) return;
-
- nr= pupmenu("Specials%t|Set Tex%x1| Shared%x2| Light%x3| Invisible%x4| Collision%x5| TwoSide%x6|Clr Tex%x7| Shared%x8| Light%x9| Invisible%x10| Collision%x11| TwoSide%x12");
-
- tface= me->mtface;
- mface= me->mface;
- for(a=me->totface; a>0; a--, tface++, mface++) {
- if(mface->flag & ME_FACE_SEL) {
- switch(nr) {
- case 1:
- tface->mode |= TF_TEX; break;
- case 2:
- tface->mode |= TF_SHAREDCOL; break;
- case 3:
- tface->mode |= TF_LIGHT; break;
- case 4:
- tface->mode |= TF_INVISIBLE; break;
- case 5:
- tface->mode |= TF_DYNAMIC; break;
- case 6:
- tface->mode |= TF_TWOSIDE; break;
- case 7:
- tface->mode &= ~TF_TEX;
- tface->tpage= NULL;
- break;
- case 8:
- tface->mode &= ~TF_SHAREDCOL; break;
- case 9:
- tface->mode &= ~TF_LIGHT; break;
- case 10:
- tface->mode &= ~TF_INVISIBLE; break;
- case 11:
- tface->mode &= ~TF_DYNAMIC; break;
- case 12:
- tface->mode &= ~TF_TWOSIDE; break;
- }
- }
- }
- DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
- }
- else if(ob->mode & OB_MODE_VERTEX_PAINT) {
- Mesh *me= get_mesh(ob);
-
- if(me==NULL || (me->mcol==NULL && me->mtface==NULL) ) return;
-
- nr= pupmenu("Specials%t|Shared VertexCol%x1");
- if(nr==1) {
-
-// XXX do_shared_vertexcol(me);
-
- DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
- }
- }
- else if(ob->mode & OB_MODE_WEIGHT_PAINT) {
- Object *par= modifiers_isDeformedByArmature(ob);
-
- if(par && (par->mode & OB_MODE_POSE)) {
-// XXX nr= pupmenu("Specials%t|Apply Bone Envelopes to Vertex Groups %x1|Apply Bone Heat Weights to Vertex Groups %x2");
-
-// XXX if(nr==1 || nr==2)
-// XXX pose_adds_vgroups(ob, (nr == 2));
- }
- }
- else if(ob->mode & OB_MODE_PARTICLE_EDIT) {
-#if 0
- // XXX
- ParticleSystem *psys = PE_get_current(ob);
- ParticleEditSettings *pset = PE_settings();
-
- if(!psys)
- return;
-
- if(pset->selectmode & SCE_SELECT_POINT)
- nr= pupmenu("Specials%t|Rekey%x1|Subdivide%x2|Select First%x3|Select Last%x4|Remove Doubles%x5");
- else
- nr= pupmenu("Specials%t|Rekey%x1|Remove Doubles%x5");
-
- switch(nr) {
- case 1:
-// XXX if(button(&pset->totrekey, 2, 100, "Number of Keys:")==0) return;
- waitcursor(1);
- PE_rekey();
- break;
- case 2:
- PE_subdivide();
- break;
- case 3:
- PE_select_root();
- break;
- case 4:
- PE_select_tip();
- break;
- case 5:
- PE_remove_doubles();
- break;
- }
-
- DAG_id_tag_update(&obedit->id, OB_RECALC_DATA);
-
- if(nr>0) waitcursor(0);
-#endif
- }
- else {
- Base *base, *base_select= NULL;
-
- /* Get the active object mesh. */
- Mesh *me= get_mesh(ob);
-
- /* Booleans, if the active object is a mesh... */
- if (me && ob->id.lib==NULL) {
-
- /* Bring up a little menu with the boolean operation choices on. */
- nr= pupmenu("Boolean Tools%t|Intersect%x1|Union%x2|Difference%x3|Add Intersect Modifier%x4|Add Union Modifier%x5|Add Difference Modifier%x6");
-
- if (nr > 0) {
- /* user has made a choice of a menu element.
- All of the boolean functions require 2 mesh objects
- we search through the object list to find the other
- selected item and make sure it is distinct and a mesh. */
-
- for(base= FIRSTBASE; base; base= base->next) {
- if(TESTBASELIB(v3d, base)) {
- if(base->object != ob) base_select= base;
- }
- }
-
- if (base_select) {
- if (get_mesh(base_select->object)) {
- if(nr <= 3){
- waitcursor(1);
-// XXX ret = NewBooleanMesh(BASACT,base_select,nr);
- if (ret==0) {
- error("An internal error occurred");
- } else if(ret==-1) {
- error("Selected meshes must have faces to perform boolean operations");
- } else if (ret==-2) {
- error("Both meshes must be a closed mesh");
- }
- waitcursor(0);
- } else {
- BooleanModifierData *bmd = NULL;
- bmd = (BooleanModifierData *)modifier_new(eModifierType_Boolean);
- BLI_addtail(&ob->modifiers, bmd);
- modifier_unique_name(&ob->modifiers, (ModifierData*)bmd);
- bmd->object = base_select->object;
- bmd->modifier.mode |= eModifierMode_Realtime;
- switch(nr){
- case 4: bmd->operation = eBooleanModifierOp_Intersect; break;
- case 5: bmd->operation = eBooleanModifierOp_Union; break;
- case 6: bmd->operation = eBooleanModifierOp_Difference; break;
- }
-// XXX do_common_editbuts(B_CHANGEDEP);
- }
- } else {
- error("Please select 2 meshes");
- }
- } else {
- error("Please select 2 meshes");
- }
- }
-
- }
- else if (ob->type == OB_FONT) {
- /* removed until this gets a decent implementation (ton) */
-/* nr= pupmenu("Split %t|Characters%x1");
- if (nr > 0) {
- switch(nr) {
- case 1: split_font();
- }
- }
-*/
- }
- }
- }
- else if(obedit->type==OB_MESH) {
- }
- else if(ELEM(obedit->type, OB_CURVE, OB_SURF)) {
- }
- else if(obedit->type==OB_ARMATURE) {
- nr= pupmenu("Specials%t|Subdivide %x1|Subdivide Multi%x2|Switch Direction%x7|Flip Left-Right Names%x3|%l|AutoName Left-Right%x4|AutoName Front-Back%x5|AutoName Top-Bottom%x6");
-// if(nr==1)
-// XXX subdivide_armature(1);
- if(nr==2) {
-// XXX if(button(&numcuts, 1, 128, "Number of Cuts:")==0) return;
- waitcursor(1);
-// XXX subdivide_armature(numcuts);
- }
-// else if(nr==3)
-// XXX armature_flip_names();
- else if(ELEM3(nr, 4, 5, 6)) {
-// XXX armature_autoside_names(nr-4);
- }
-// else if(nr == 7)
-// XXX switch_direction_armature();
- }
- else if(obedit->type==OB_LATTICE) {
- Lattice *lt= obedit->data;
- static float weight= 1.0f;
- { // XXX
-// XXX if(fbutton(&weight, 0.0f, 1.0f, 10, 10, "Set Weight")) {
- Lattice *editlt= lt->editlatt->latt;
- int a= editlt->pntsu*editlt->pntsv*editlt->pntsw;
- BPoint *bp= editlt->def;
-
- while(a--) {
- if(bp->f1 & SELECT)
- bp->weight= weight;
- bp++;
- }
- }
- }
-
-}
-
static void copymenu_properties(Scene *scene, View3D *v3d, Object *ob)
{
//XXX no longer used - to be removed - replaced by game_properties_copy_exec
@@ -1674,102 +1443,6 @@ static void UNUSED_FUNCTION(image_aspect)(Scene *scene, View3D *v3d)
}
-static int vergbaseco(const void *a1, const void *a2)
-{
- Base **x1, **x2;
-
- x1= (Base **) a1;
- x2= (Base **) a2;
-
- if( (*x1)->sy > (*x2)->sy ) return 1;
- else if( (*x1)->sy < (*x2)->sy) return -1;
- else if( (*x1)->sx > (*x2)->sx ) return 1;
- else if( (*x1)->sx < (*x2)->sx ) return -1;
-
- return 0;
-}
-
-
-static void UNUSED_FUNCTION(auto_timeoffs)(Scene *scene, View3D *v3d)
-{
- Base *base, **basesort, **bs;
- float start, delta;
- int tot=0, a;
- short offset=25;
-
- if(BASACT==NULL || v3d==NULL) return;
-// XXX if(button(&offset, 0, 1000,"Total time")==0) return;
-
- /* make array of all bases, xco yco (screen) */
- for(base= FIRSTBASE; base; base= base->next) {
- if(TESTBASELIB(v3d, base)) {
- tot++;
- }
- }
-
- delta= (float)offset/(float)tot;
- start= OBACT->sf;
-
- bs= basesort= MEM_mallocN(sizeof(void *)*tot,"autotimeoffs");
- for(base= FIRSTBASE; base; base= base->next) {
- if(TESTBASELIB(v3d, base)) {
- *bs= base;
- bs++;
- }
- }
- qsort(basesort, tot, sizeof(void *), vergbaseco);
-
- bs= basesort;
- for(a=0; a<tot; a++) {
-
- (*bs)->object->sf= start;
- start+= delta;
-
- bs++;
- }
- MEM_freeN(basesort);
-
-}
-
-static void UNUSED_FUNCTION(ofs_timeoffs)(Scene *scene, View3D *v3d)
-{
- float offset=0.0f;
-
- if(BASACT==NULL || v3d==NULL) return;
-
-// XXX if(fbutton(&offset, -10000.0f, 10000.0f, 10, 10, "Offset")==0) return;
-
- /* make array of all bases, xco yco (screen) */
- CTX_DATA_BEGIN(evil_C, Object*, ob, selected_editable_objects) {
- ob->sf += offset;
- if (ob->sf < -MAXFRAMEF) ob->sf = -MAXFRAMEF;
- else if (ob->sf > MAXFRAMEF) ob->sf = MAXFRAMEF;
- }
- CTX_DATA_END;
-
-}
-
-
-static void UNUSED_FUNCTION(rand_timeoffs)(Scene *scene, View3D *v3d)
-{
- Base *base;
- float rand_ofs=0.0f;
-
- if(BASACT==NULL || v3d==NULL) return;
-
-// XXX if(fbutton(&rand_ofs, 0.0f, 10000.0f, 10, 10, "Randomize")==0) return;
-
- rand_ofs *= 2;
-
- for(base= FIRSTBASE; base; base= base->next) {
- if(TESTBASELIB(v3d, base)) {
- base->object->sf += ((float)BLI_drand()-0.5f) * rand_ofs;
- if (base->object->sf < -MAXFRAMEF) base->object->sf = -MAXFRAMEF;
- else if (base->object->sf > MAXFRAMEF) base->object->sf = MAXFRAMEF;
- }
- }
-
-}
static EnumPropertyItem *object_mode_set_itemsf(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), int *free)
{
@@ -1932,16 +1605,21 @@ void ED_object_toggle_modes(bContext *C, int mode)
/************************ Game Properties ***********************/
-static int game_property_new(bContext *C, wmOperator *UNUSED(op))
+static int game_property_new(bContext *C, wmOperator *op)
{
Object *ob= CTX_data_active_object(C);
bProperty *prop;
+ char name[32];
+ int type= RNA_enum_get(op->ptr, "type");
- if(!ob)
- return OPERATOR_CANCELLED;
-
- prop= new_property(PROP_FLOAT);
+ prop= new_property(type);
BLI_addtail(&ob->prop, prop);
+
+ RNA_string_get(op->ptr, "name", name);
+ if (name[0] != '\0') {
+ BLI_strncpy(prop->name, name, sizeof(prop->name));
+ }
+
unique_property(NULL, prop, 0); // make_unique_prop_names(prop->name);
WM_event_add_notifier(C, NC_LOGIC, NULL);
@@ -1962,6 +1640,9 @@ void OBJECT_OT_game_property_new(wmOperatorType *ot)
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ RNA_def_enum(ot->srna, "type", gameproperty_type_items, 2, "Type", "Type of game property to add");
+ RNA_def_string(ot->srna, "name", "", 32, "Name", "Name of the game property to add");
}
static int game_property_remove(bContext *C, wmOperator *op)
diff --git a/source/blender/editors/object/object_group.c b/source/blender/editors/object/object_group.c
index bf0439b7044..74cf174d7b4 100644
--- a/source/blender/editors/object/object_group.c
+++ b/source/blender/editors/object/object_group.c
@@ -46,6 +46,7 @@
#include "BKE_report.h"
#include "ED_screen.h"
+#include "ED_object.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -230,7 +231,7 @@ void GROUP_OT_create(wmOperatorType *ot)
static int group_add_exec(bContext *C, wmOperator *UNUSED(op))
{
Scene *scene= CTX_data_scene(C);
- Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ Object *ob= ED_object_context(C);
Group *group;
if(ob == NULL)
@@ -261,7 +262,7 @@ void OBJECT_OT_group_add(wmOperatorType *ot)
static int group_link_exec(bContext *C, wmOperator *op)
{
Scene *scene= CTX_data_scene(C);
- Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ Object *ob= ED_object_context(C);
Group *group= BLI_findlink(&CTX_data_main(C)->group, RNA_enum_get(op->ptr, "group"));
if(ELEM(NULL, ob, group))
@@ -299,7 +300,7 @@ void OBJECT_OT_group_link(wmOperatorType *ot)
static int group_remove_exec(bContext *C, wmOperator *UNUSED(op))
{
Scene *scene= CTX_data_scene(C);
- Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ Object *ob= ED_object_context(C);
Group *group= CTX_data_pointer_get_type(C, "group", &RNA_Group).data;
if(!ob || !group)
diff --git a/source/blender/editors/object/object_shapekey.c b/source/blender/editors/object/object_shapekey.c
index 28f9c88f950..956ec868104 100644
--- a/source/blender/editors/object/object_shapekey.c
+++ b/source/blender/editors/object/object_shapekey.c
@@ -61,6 +61,7 @@
#include "BLO_sys_types.h" // for intptr_t support
+#include "ED_object.h"
#include "ED_mesh.h"
#include "RNA_access.h"
@@ -269,14 +270,14 @@ static int object_shape_key_mirror(bContext *C, Object *ob)
static int shape_key_mode_poll(bContext *C)
{
- Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ Object *ob= ED_object_context(C);
ID *data= (ob)? ob->data: NULL;
return (ob && !ob->id.lib && data && !data->lib && ob->mode != OB_MODE_EDIT);
}
static int shape_key_poll(bContext *C)
{
- Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ Object *ob= ED_object_context(C);
ID *data= (ob)? ob->data: NULL;
return (ob && !ob->id.lib && data && !data->lib);
}
@@ -284,7 +285,7 @@ static int shape_key_poll(bContext *C)
static int shape_key_add_exec(bContext *C, wmOperator *op)
{
Scene *scene= CTX_data_scene(C);
- Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ Object *ob= ED_object_context(C);
int from_mix = RNA_boolean_get(op->ptr, "from_mix");
ED_object_shape_key_add(C, scene, ob, from_mix);
@@ -312,7 +313,7 @@ void OBJECT_OT_shape_key_add(wmOperatorType *ot)
static int shape_key_remove_exec(bContext *C, wmOperator *UNUSED(op))
{
- Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ Object *ob= ED_object_context(C);
if(!ED_object_shape_key_remove(C, ob))
return OPERATOR_CANCELLED;
@@ -337,7 +338,7 @@ void OBJECT_OT_shape_key_remove(wmOperatorType *ot)
static int shape_key_clear_exec(bContext *C, wmOperator *UNUSED(op))
{
- Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ Object *ob= ED_object_context(C);
Key *key= ob_get_key(ob);
KeyBlock *kb= ob_get_keyblock(ob);
@@ -370,7 +371,7 @@ void OBJECT_OT_shape_key_clear(wmOperatorType *ot)
static int shape_key_mirror_exec(bContext *C, wmOperator *UNUSED(op))
{
- Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ Object *ob= ED_object_context(C);
if(!object_shape_key_mirror(C, ob))
return OPERATOR_CANCELLED;
@@ -395,7 +396,7 @@ void OBJECT_OT_shape_key_mirror(wmOperatorType *ot)
static int shape_key_move_exec(bContext *C, wmOperator *op)
{
- Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ Object *ob= ED_object_context(C);
int type= RNA_enum_get(op->ptr, "type");
Key *key= ob_get_key(ob);
diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c
index bfb5d166e6f..dfe0b94605d 100644
--- a/source/blender/editors/object/object_vgroup.c
+++ b/source/blender/editors/object/object_vgroup.c
@@ -67,6 +67,7 @@
#include "WM_api.h"
#include "WM_types.h"
+#include "ED_object.h"
#include "ED_mesh.h"
#include "UI_resources.h"
@@ -582,23 +583,47 @@ static void vgroup_select_verts(Object *ob, int select)
if(ob->type == OB_MESH) {
Mesh *me= ob->data;
- EditMesh *em = BKE_mesh_get_editmesh(me);
- EditVert *eve;
- for (eve=em->verts.first; eve; eve=eve->next) {
- if (!eve->h) {
- dv= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT);
- if (defvert_find_index(dv, def_nr)) {
- if (select) eve->f |= SELECT;
- else eve->f &= ~SELECT;
+ if (me->edit_mesh) {
+ EditMesh *em = BKE_mesh_get_editmesh(me);
+ EditVert *eve;
+
+ for (eve=em->verts.first; eve; eve=eve->next) {
+ if (!eve->h) {
+ dv= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT);
+ if (defvert_find_index(dv, def_nr)) {
+ if (select) eve->f |= SELECT;
+ else eve->f &= ~SELECT;
+ }
}
}
+ /* this has to be called, because this function operates on vertices only */
+ if(select) EM_select_flush(em); // vertices to edges/faces
+ else EM_deselect_flush(em);
+
+ BKE_mesh_end_editmesh(me, em);
}
- /* this has to be called, because this function operates on vertices only */
- if(select) EM_select_flush(em); // vertices to edges/faces
- else EM_deselect_flush(em);
+ else {
+ if (me->dvert) {
+ MVert *mv;
+ MDeformVert *dv;
+ int i;
+
+ mv = me->mvert;
+ dv = me->dvert;
+
+ for (i=0; i<me->totvert; i++, mv++, dv++) {
+ if (!(mv->flag & ME_HIDE)) {
+ if (defvert_find_index(dv, def_nr)) {
+ if (select) mv->flag |= SELECT;
+ else mv->flag &= ~SELECT;
+ }
+ }
+ }
- BKE_mesh_end_editmesh(me, em);
+ paintvert_flush_flags(ob);
+ }
+ }
}
else if(ob->type == OB_LATTICE) {
Lattice *lt= vgroup_edit_lattice(ob);
@@ -1740,23 +1765,47 @@ static void vgroup_delete_object_mode(Object *ob, bDeformGroup *dg)
/* removes from active defgroup, if allverts==0 only selected vertices */
static void vgroup_active_remove_verts(Object *ob, const int allverts, bDeformGroup *dg)
{
- EditVert *eve;
MDeformVert *dv;
const int def_nr= BLI_findindex(&ob->defbase, dg);
if(ob->type == OB_MESH) {
Mesh *me= ob->data;
- EditMesh *em = BKE_mesh_get_editmesh(me);
- for(eve=em->verts.first; eve; eve=eve->next){
- dv= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT);
+ if (me->edit_mesh) {
+ EditVert *eve;
+ EditMesh *em = BKE_mesh_get_editmesh(me);
- if(dv && dv->dw && (allverts || (eve->f & SELECT))){
- MDeformWeight *dw = defvert_find_index(dv, def_nr);
- defvert_remove_group(dv, dw); /* dw can be NULL */
+ for (eve=em->verts.first; eve; eve=eve->next) {
+ dv= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT);
+
+ if (dv && dv->dw && (allverts || (eve->f & SELECT))) {
+ MDeformWeight *dw = defvert_find_index(dv, def_nr);
+ defvert_remove_group(dv, dw); /* dw can be NULL */
+ }
+ }
+ BKE_mesh_end_editmesh(me, em);
+ }
+ else {
+ MVert *mv;
+ MDeformVert *dv;
+ int i;
+
+ if (!me->dvert) {
+ ED_vgroup_data_create(&me->id);
+ }
+
+ mv = me->mvert;
+ dv = me->dvert;
+
+ for (i=0; i<me->totvert; i++, mv++, dv++) {
+ if (mv->flag & SELECT) {
+ if (dv->dw && (allverts || (mv->flag & SELECT))) {
+ MDeformWeight *dw = defvert_find_index(dv, def_nr);
+ defvert_remove_group(dv, dw); /* dw can be NULL */
+ }
+ }
}
}
- BKE_mesh_end_editmesh(me, em);
}
else if(ob->type == OB_LATTICE) {
Lattice *lt= vgroup_edit_lattice(ob);
@@ -1861,6 +1910,18 @@ static int vgroup_object_in_edit_mode(Object *ob)
return 0;
}
+static int vgroup_object_in_wpaint_vert_select(Object *ob)
+{
+ if (ob->type == OB_MESH) {
+ Mesh *me = ob->data;
+ return ( (ob->mode & OB_MODE_WEIGHT_PAINT) &&
+ (me->edit_mesh == NULL) &&
+ (ME_EDIT_PAINT_SEL_MODE(me) == SCE_SELECT_VERTEX) );
+ }
+
+ return 0;
+}
+
static void vgroup_delete(Object *ob)
{
bDeformGroup *dg = BLI_findlink(&ob->defbase, ob->actdef-1);
@@ -1907,24 +1968,48 @@ static void vgroup_assign_verts(Object *ob, const float weight)
if(ob->type == OB_MESH) {
Mesh *me= ob->data;
- EditMesh *em = BKE_mesh_get_editmesh(me);
- EditVert *eve;
+ if (me->edit_mesh) {
+ EditMesh *em = BKE_mesh_get_editmesh(me);
+ EditVert *eve;
- if(!CustomData_has_layer(&em->vdata, CD_MDEFORMVERT))
- EM_add_data_layer(em, &em->vdata, CD_MDEFORMVERT, NULL);
+ if(!CustomData_has_layer(&em->vdata, CD_MDEFORMVERT))
+ EM_add_data_layer(em, &em->vdata, CD_MDEFORMVERT, NULL);
- /* Go through the list of editverts and assign them */
- for (eve=em->verts.first; eve; eve=eve->next) {
- if (eve->f & SELECT) {
- MDeformWeight *dw;
- dv= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT); /* can be NULL */
- dw= defvert_verify_index(dv, def_nr);
- if (dw) {
- dw->weight= weight;
+ /* Go through the list of editverts and assign them */
+ for (eve=em->verts.first; eve; eve=eve->next) {
+ if (eve->f & SELECT) {
+ MDeformWeight *dw;
+ dv= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT); /* can be NULL */
+ dw= defvert_verify_index(dv, def_nr);
+ if (dw) {
+ dw->weight= weight;
+ }
+ }
+ }
+ BKE_mesh_end_editmesh(me, em);
+ }
+ else {
+ MVert *mv;
+ MDeformVert *dv;
+ int i;
+
+ if (!me->dvert) {
+ ED_vgroup_data_create(&me->id);
+ }
+
+ mv = me->mvert;
+ dv = me->dvert;
+
+ for (i=0; i<me->totvert; i++, mv++, dv++) {
+ if (mv->flag & SELECT) {
+ MDeformWeight *dw;
+ dw= defvert_verify_index(dv, def_nr);
+ if (dw) {
+ dw->weight= weight;
+ }
}
}
}
- BKE_mesh_end_editmesh(me, em);
}
else if(ob->type == OB_LATTICE) {
Lattice *lt= vgroup_edit_lattice(ob);
@@ -1968,14 +2053,14 @@ static void vgroup_remove_verts(Object *ob, int allverts)
static int vertex_group_poll(bContext *C)
{
- Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ Object *ob= ED_object_context(C);
ID *data= (ob)? ob->data: NULL;
return (ob && !ob->id.lib && OB_TYPE_SUPPORT_VGROUP(ob->type) && data && !data->lib);
}
static int vertex_group_poll_edit(bContext *C)
{
- Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ Object *ob= ED_object_context(C);
ID *data= (ob)? ob->data: NULL;
if(!(ob && !ob->id.lib && data && !data->lib))
@@ -1984,9 +2069,22 @@ static int vertex_group_poll_edit(bContext *C)
return vgroup_object_in_edit_mode(ob);
}
+/* editmode _or_ weight paint vertex sel */
+static int vertex_group_poll_edit_or_wpaint_vert_select(bContext *C)
+{
+ Object *ob= ED_object_context(C);
+ ID *data= (ob)? ob->data: NULL;
+
+ if(!(ob && !ob->id.lib && data && !data->lib))
+ return 0;
+
+ return ( vgroup_object_in_edit_mode(ob) ||
+ vgroup_object_in_wpaint_vert_select(ob) );
+}
+
static int vertex_group_add_exec(bContext *C, wmOperator *UNUSED(op))
{
- Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ Object *ob= ED_object_context(C);
ED_vgroup_add(ob);
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
@@ -2012,7 +2110,7 @@ void OBJECT_OT_vertex_group_add(wmOperatorType *ot)
static int vertex_group_remove_exec(bContext *C, wmOperator *op)
{
- Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ Object *ob= ED_object_context(C);
if(RNA_boolean_get(op->ptr, "all"))
vgroup_delete_all(ob);
@@ -2049,7 +2147,7 @@ void OBJECT_OT_vertex_group_remove(wmOperatorType *ot)
static int vertex_group_assign_exec(bContext *C, wmOperator *op)
{
ToolSettings *ts= CTX_data_tool_settings(C);
- Object *ob= CTX_data_edit_object(C);
+ Object *ob= ED_object_context(C);
if(RNA_boolean_get(op->ptr, "new"))
ED_vgroup_add(ob);
@@ -2068,7 +2166,7 @@ void OBJECT_OT_vertex_group_assign(wmOperatorType *ot)
ot->idname= "OBJECT_OT_vertex_group_assign";
/* api callbacks */
- ot->poll= vertex_group_poll_edit;
+ ot->poll= vertex_group_poll_edit_or_wpaint_vert_select;
ot->exec= vertex_group_assign_exec;
/* flags */
@@ -2083,7 +2181,7 @@ void OBJECT_OT_vertex_group_assign(wmOperatorType *ot)
static int vertex_group_remove_from_exec(bContext *C, wmOperator *op)
{
- Object *ob= CTX_data_edit_object(C);
+ Object *ob= ED_object_context(C);
if(RNA_boolean_get(op->ptr, "all"))
vgroup_remove_verts(ob, 0);
@@ -2110,7 +2208,7 @@ void OBJECT_OT_vertex_group_remove_from(wmOperatorType *ot)
ot->idname= "OBJECT_OT_vertex_group_remove_from";
/* api callbacks */
- ot->poll= vertex_group_poll_edit;
+ ot->poll= vertex_group_poll_edit_or_wpaint_vert_select;
ot->exec= vertex_group_remove_from_exec;
/* flags */
@@ -2125,7 +2223,7 @@ void OBJECT_OT_vertex_group_remove_from(wmOperatorType *ot)
static int vertex_group_select_exec(bContext *C, wmOperator *UNUSED(op))
{
- Object *ob= CTX_data_edit_object(C);
+ Object *ob= ED_object_context(C);
if(!ob || ob->id.lib)
return OPERATOR_CANCELLED;
@@ -2143,7 +2241,7 @@ void OBJECT_OT_vertex_group_select(wmOperatorType *ot)
ot->idname= "OBJECT_OT_vertex_group_select";
/* api callbacks */
- ot->poll= vertex_group_poll_edit;
+ ot->poll= vertex_group_poll_edit_or_wpaint_vert_select;
ot->exec= vertex_group_select_exec;
/* flags */
@@ -2152,7 +2250,7 @@ void OBJECT_OT_vertex_group_select(wmOperatorType *ot)
static int vertex_group_deselect_exec(bContext *C, wmOperator *UNUSED(op))
{
- Object *ob= CTX_data_edit_object(C);
+ Object *ob= ED_object_context(C);
vgroup_select_verts(ob, 0);
WM_event_add_notifier(C, NC_GEOM|ND_SELECT, ob->data);
@@ -2167,7 +2265,7 @@ void OBJECT_OT_vertex_group_deselect(wmOperatorType *ot)
ot->idname= "OBJECT_OT_vertex_group_deselect";
/* api callbacks */
- ot->poll= vertex_group_poll_edit;
+ ot->poll= vertex_group_poll_edit_or_wpaint_vert_select;
ot->exec= vertex_group_deselect_exec;
/* flags */
@@ -2176,7 +2274,7 @@ void OBJECT_OT_vertex_group_deselect(wmOperatorType *ot)
static int vertex_group_copy_exec(bContext *C, wmOperator *UNUSED(op))
{
- Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ Object *ob= ED_object_context(C);
vgroup_duplicate(ob);
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
@@ -2202,7 +2300,7 @@ void OBJECT_OT_vertex_group_copy(wmOperatorType *ot)
static int vertex_group_levels_exec(bContext *C, wmOperator *op)
{
- Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ Object *ob= ED_object_context(C);
float offset= RNA_float_get(op->ptr,"offset");
float gain= RNA_float_get(op->ptr,"gain");
@@ -2235,7 +2333,7 @@ void OBJECT_OT_vertex_group_levels(wmOperatorType *ot)
static int vertex_group_normalize_exec(bContext *C, wmOperator *UNUSED(op))
{
- Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ Object *ob= ED_object_context(C);
vgroup_normalize(ob);
@@ -2262,7 +2360,7 @@ void OBJECT_OT_vertex_group_normalize(wmOperatorType *ot)
static int vertex_group_normalize_all_exec(bContext *C, wmOperator *op)
{
- Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ Object *ob= ED_object_context(C);
int lock_active= RNA_boolean_get(op->ptr,"lock_active");
vgroup_normalize_all(ob, lock_active);
@@ -2372,7 +2470,7 @@ void OBJECT_OT_vertex_group_lock(wmOperatorType *ot)
static int vertex_group_invert_exec(bContext *C, wmOperator *op)
{
- Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ Object *ob= ED_object_context(C);
int auto_assign= RNA_boolean_get(op->ptr,"auto_assign");
int auto_remove= RNA_boolean_get(op->ptr,"auto_remove");
@@ -2406,7 +2504,7 @@ void OBJECT_OT_vertex_group_invert(wmOperatorType *ot)
static int vertex_group_blend_exec(bContext *C, wmOperator *UNUSED(op))
{
- Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ Object *ob= ED_object_context(C);
vgroup_blend(ob);
@@ -2435,7 +2533,7 @@ void OBJECT_OT_vertex_group_blend(wmOperatorType *ot)
static int vertex_group_clean_exec(bContext *C, wmOperator *op)
{
- Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ Object *ob= ED_object_context(C);
float limit= RNA_float_get(op->ptr,"limit");
int all_groups= RNA_boolean_get(op->ptr,"all_groups");
@@ -2474,7 +2572,7 @@ void OBJECT_OT_vertex_group_clean(wmOperatorType *ot)
static int vertex_group_mirror_exec(bContext *C, wmOperator *op)
{
- Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ Object *ob= ED_object_context(C);
ED_vgroup_mirror(ob,
RNA_boolean_get(op->ptr,"mirror_weights"),
@@ -2513,7 +2611,7 @@ void OBJECT_OT_vertex_group_mirror(wmOperatorType *ot)
static int vertex_group_copy_to_linked_exec(bContext *C, wmOperator *UNUSED(op))
{
Scene *scene= CTX_data_scene(C);
- Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ Object *ob= ED_object_context(C);
Base *base;
int retval= OPERATOR_CANCELLED;
@@ -2553,7 +2651,7 @@ void OBJECT_OT_vertex_group_copy_to_linked(wmOperatorType *ot)
static int vertex_group_copy_to_selected_exec(bContext *C, wmOperator *op)
{
- Object *obact= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ Object *obact= ED_object_context(C);
int change= 0;
int fail= 0;
@@ -2596,7 +2694,7 @@ static EnumPropertyItem vgroup_items[]= {
static int set_active_group_exec(bContext *C, wmOperator *op)
{
- Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ Object *ob= ED_object_context(C);
int nr= RNA_enum_get(op->ptr, "group");
BLI_assert(nr+1 >= 0);
@@ -2610,7 +2708,7 @@ static int set_active_group_exec(bContext *C, wmOperator *op)
static EnumPropertyItem *vgroup_itemf(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), int *free)
{
- Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ Object *ob= ED_object_context(C);
EnumPropertyItem tmp = {0, "", 0, "", ""};
EnumPropertyItem *item= NULL;
bDeformGroup *def;
@@ -2751,7 +2849,7 @@ static int vgroup_sort(void *def_a_ptr, void *def_b_ptr)
static int vertex_group_sort_exec(bContext *C, wmOperator *op)
{
- Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ Object *ob= ED_object_context(C);
char *name_array;
int ret;
@@ -2790,7 +2888,7 @@ void OBJECT_OT_vertex_group_sort(wmOperatorType *ot)
static int vgroup_move_exec(bContext *C, wmOperator *op)
{
- Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ Object *ob= ED_object_context(C);
bDeformGroup *def;
char *name_array;
int dir= RNA_enum_get(op->ptr, "direction"), ret;
diff --git a/source/blender/editors/physics/dynamicpaint_ops.c b/source/blender/editors/physics/dynamicpaint_ops.c
index 6e25307b786..cdcaae91070 100644
--- a/source/blender/editors/physics/dynamicpaint_ops.c
+++ b/source/blender/editors/physics/dynamicpaint_ops.c
@@ -42,6 +42,7 @@
#include "ED_mesh.h"
#include "ED_screen.h"
+#include "ED_object.h"
#include "RNA_access.h"
#include "RNA_define.h"
@@ -58,7 +59,7 @@
static int surface_slot_add_exec(bContext *C, wmOperator *UNUSED(op))
{
DynamicPaintModifierData *pmd = NULL;
- Object *cObject = CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ Object *cObject = ED_object_context(C);
DynamicPaintCanvasSettings *canvas;
DynamicPaintSurface *surface;
@@ -100,7 +101,7 @@ void DPAINT_OT_surface_slot_add(wmOperatorType *ot)
static int surface_slot_remove_exec(bContext *C, wmOperator *UNUSED(op))
{
DynamicPaintModifierData *pmd = NULL;
- Object *cObject = CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ Object *cObject = ED_object_context(C);
DynamicPaintCanvasSettings *canvas;
DynamicPaintSurface *surface;
int id=0;
@@ -148,7 +149,7 @@ void DPAINT_OT_surface_slot_remove(wmOperatorType *ot)
static int type_toggle_exec(bContext *C, wmOperator *op)
{
- Object *cObject = CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ Object *cObject = ED_object_context(C);
Scene *scene = CTX_data_scene(C);
DynamicPaintModifierData *pmd = (DynamicPaintModifierData *)modifiers_findByType(cObject, eModifierType_DynamicPaint);
int type= RNA_enum_get(op->ptr, "type");
@@ -199,7 +200,7 @@ void DPAINT_OT_type_toggle(wmOperatorType *ot)
static int output_toggle_exec(bContext *C, wmOperator *op)
{
- Object *ob = CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ Object *ob = ED_object_context(C);
Scene *scene = CTX_data_scene(C);
DynamicPaintSurface *surface;
DynamicPaintModifierData *pmd = (DynamicPaintModifierData *)modifiers_findByType(ob, eModifierType_DynamicPaint);
@@ -344,7 +345,7 @@ static int dynamicPaint_initBake(struct bContext *C, struct wmOperator *op)
{
DynamicPaintModifierData *pmd = NULL;
DynamicPaintCanvasSettings *canvas;
- Object *ob = CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ Object *ob = ED_object_context(C);
int status = 0;
double timer = PIL_check_seconds_timer();
char result_str[80];
diff --git a/source/blender/editors/physics/particle_object.c b/source/blender/editors/physics/particle_object.c
index bbff2239a38..b26661da4a2 100644
--- a/source/blender/editors/physics/particle_object.c
+++ b/source/blender/editors/physics/particle_object.c
@@ -59,6 +59,7 @@
#include "ED_particle.h"
#include "ED_screen.h"
+#include "ED_object.h"
#include "physics_intern.h"
@@ -66,7 +67,7 @@
static int particle_system_add_exec(bContext *C, wmOperator *UNUSED(op))
{
- Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ Object *ob= ED_object_context(C);
Scene *scene = CTX_data_scene(C);
if(!scene || !ob)
@@ -97,7 +98,7 @@ void OBJECT_OT_particle_system_add(wmOperatorType *ot)
static int particle_system_remove_exec(bContext *C, wmOperator *UNUSED(op))
{
- Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ Object *ob= ED_object_context(C);
Scene *scene = CTX_data_scene(C);
int mode_orig = ob->mode;
if(!scene || !ob)
@@ -581,7 +582,7 @@ static void disconnect_hair(Scene *scene, Object *ob, ParticleSystem *psys)
static int disconnect_hair_exec(bContext *C, wmOperator *op)
{
Scene *scene= CTX_data_scene(C);
- Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ Object *ob= ED_object_context(C);
PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
ParticleSystem *psys= NULL;
int all = RNA_boolean_get(op->ptr, "all");
@@ -719,7 +720,7 @@ static void connect_hair(Scene *scene, Object *ob, ParticleSystem *psys)
static int connect_hair_exec(bContext *C, wmOperator *op)
{
Scene *scene= CTX_data_scene(C);
- Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ Object *ob= ED_object_context(C);
PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
ParticleSystem *psys= NULL;
int all = RNA_boolean_get(op->ptr, "all");
diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c
index 96018de130b..937f43dfadb 100644
--- a/source/blender/editors/render/render_shading.c
+++ b/source/blender/editors/render/render_shading.c
@@ -77,6 +77,7 @@
#include "WM_api.h"
#include "WM_types.h"
+#include "ED_object.h"
#include "ED_curve.h"
#include "ED_mesh.h"
#include "ED_node.h"
@@ -95,7 +96,7 @@
static int material_slot_add_exec(bContext *C, wmOperator *UNUSED(op))
{
- Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ Object *ob= ED_object_context(C);
if(!ob)
return OPERATOR_CANCELLED;
@@ -124,7 +125,7 @@ void OBJECT_OT_material_slot_add(wmOperatorType *ot)
static int material_slot_remove_exec(bContext *C, wmOperator *op)
{
- Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ Object *ob= ED_object_context(C);
if(!ob)
return OPERATOR_CANCELLED;
@@ -160,7 +161,7 @@ void OBJECT_OT_material_slot_remove(wmOperatorType *ot)
static int material_slot_assign_exec(bContext *C, wmOperator *UNUSED(op))
{
- Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ Object *ob= ED_object_context(C);
if(!ob)
return OPERATOR_CANCELLED;
@@ -220,7 +221,7 @@ void OBJECT_OT_material_slot_assign(wmOperatorType *ot)
static int material_slot_de_select(bContext *C, int select)
{
- Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ Object *ob= ED_object_context(C);
if(!ob)
return OPERATOR_CANCELLED;
@@ -326,7 +327,7 @@ void OBJECT_OT_material_slot_deselect(wmOperatorType *ot)
static int material_slot_copy_exec(bContext *C, wmOperator *UNUSED(op))
{
- Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ Object *ob= ED_object_context(C);
Material ***matar;
if(!ob || !(matar= give_matarar(ob)))
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index ffdfea7fde5..98f85009140 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -3309,7 +3309,6 @@ static void SCREEN_OT_delete(wmOperatorType *ot)
static int scene_new_exec(bContext *C, wmOperator *op)
{
Scene *newscene, *scene= CTX_data_scene(C);
- bScreen *screen= CTX_wm_screen(C);
Main *bmain= CTX_data_main(C);
int type= RNA_enum_get(op->ptr, "type");
@@ -3328,11 +3327,9 @@ static int scene_new_exec(bContext *C, wmOperator *op)
}
}
- /* this notifier calls ED_screen_set_scene, doing a lot of UI stuff, not for inside event loops */
- WM_event_add_notifier(C, NC_SCENE|ND_SCENEBROWSE, newscene);
+ ED_screen_set_scene(C, newscene);
- if(screen)
- screen->scene= newscene;
+ WM_event_add_notifier(C, NC_SCENE|ND_SCENEBROWSE, newscene);
return OPERATOR_FINISHED;
}
@@ -3368,9 +3365,14 @@ static void SCENE_OT_new(wmOperatorType *ot)
static int scene_delete_exec(bContext *C, wmOperator *UNUSED(op))
{
Scene *scene= CTX_data_scene(C);
-
+
+ ED_screen_delete_scene(C, scene);
+
+ if(G.f & G_DEBUG)
+ printf("scene delete %p\n", scene);
+
WM_event_add_notifier(C, NC_SCENE|NA_REMOVED, scene);
-
+
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/screen/screendump.c b/source/blender/editors/screen/screendump.c
index 31aab956754..fe2dc1fb913 100644
--- a/source/blender/editors/screen/screendump.c
+++ b/source/blender/editors/screen/screendump.c
@@ -278,7 +278,6 @@ static void screenshot_startjob(void *sjv, short *stop, short *do_update, float
ScreenshotJob *sj= sjv;
RenderData rd= sj->scene->r;
bMovieHandle *mh= BKE_get_movie_handle(sj->scene->r.im_format.imtype);
- int cfra= 1;
/* we need this as local variables for renderdata */
rd.frs_sec= U.scrcastfps;
@@ -303,9 +302,9 @@ static void screenshot_startjob(void *sjv, short *stop, short *do_update, float
if(sj->dumprect) {
if(mh) {
- if(mh->append_movie(&rd, cfra, (int *)sj->dumprect, sj->dumpsx, sj->dumpsy, &sj->reports)) {
- BKE_reportf(&sj->reports, RPT_INFO, "Appended frame: %d", cfra);
- printf("Appended frame %d\n", cfra);
+ if(mh->append_movie(&rd, rd.cfra, (int *)sj->dumprect, sj->dumpsx, sj->dumpsy, &sj->reports)) {
+ BKE_reportf(&sj->reports, RPT_INFO, "Appended frame: %d", rd.cfra);
+ printf("Appended frame %d\n", rd.cfra);
} else
break;
}
@@ -314,7 +313,7 @@ static void screenshot_startjob(void *sjv, short *stop, short *do_update, float
char name[FILE_MAX];
int ok;
- BKE_makepicstring(name, rd.pic, sj->bmain->name, cfra, rd.im_format.imtype, rd.scemode & R_EXTENSION, TRUE);
+ BKE_makepicstring(name, rd.pic, sj->bmain->name, rd.cfra, rd.im_format.imtype, rd.scemode & R_EXTENSION, TRUE);
ibuf->rect= sj->dumprect;
ok= BKE_write_ibuf(ibuf, name, &rd.im_format);
@@ -338,7 +337,7 @@ static void screenshot_startjob(void *sjv, short *stop, short *do_update, float
*do_update= 1;
- cfra++;
+ rd.cfra++;
}
else
diff --git a/source/blender/editors/space_buttons/buttons_texture.c b/source/blender/editors/space_buttons/buttons_texture.c
index c0ccaeaea90..6927a78332f 100644
--- a/source/blender/editors/space_buttons/buttons_texture.c
+++ b/source/blender/editors/space_buttons/buttons_texture.c
@@ -1,6 +1,4 @@
/*
- * $Id$
- *
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c
index 7b692f55965..da7f22b2030 100644
--- a/source/blender/editors/space_node/node_draw.c
+++ b/source/blender/editors/space_node/node_draw.c
@@ -233,7 +233,7 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node)
/* output sockets */
for(nsock= node->outputs.first; nsock; nsock= nsock->next) {
- if(!(nsock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) {
+ if(!nodeSocketIsHidden(nsock)) {
nsock->locx= locx + node->width;
nsock->locy= dy - NODE_DYS;
dy-= NODE_DY;
@@ -312,7 +312,7 @@ static void node_update_basis(const bContext *C, bNodeTree *ntree, bNode *node)
/* input sockets */
for(nsock= node->inputs.first; nsock; nsock= nsock->next) {
- if(!(nsock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) {
+ if(!nodeSocketIsHidden(nsock)) {
nsock->locx= locx;
nsock->locy= dy - NODE_DYS;
dy-= NODE_DY;
@@ -351,10 +351,10 @@ static void node_update_hidden(bNode *node)
/* calculate minimal radius */
for(nsock= node->inputs.first; nsock; nsock= nsock->next)
- if(!(nsock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL)) && (nsock->flag & SOCK_IN_USE))
+ if(!nodeSocketIsHidden(nsock))
totin++;
for(nsock= node->outputs.first; nsock; nsock= nsock->next)
- if(!(nsock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL)) && (nsock->flag & SOCK_IN_USE))
+ if(!nodeSocketIsHidden(nsock))
totout++;
tot= MAX2(totin, totout);
@@ -371,7 +371,7 @@ static void node_update_hidden(bNode *node)
rad=drad= (float)M_PI/(1.0f + (float)totout);
for(nsock= node->outputs.first; nsock; nsock= nsock->next) {
- if(!(nsock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL)) && (nsock->flag & SOCK_IN_USE)) {
+ if(!nodeSocketIsHidden(nsock)) {
nsock->locx= node->totr.xmax - hiddenrad + (float)sin(rad)*hiddenrad;
nsock->locy= node->totr.ymin + hiddenrad + (float)cos(rad)*hiddenrad;
rad+= drad;
@@ -382,7 +382,7 @@ static void node_update_hidden(bNode *node)
rad=drad= - (float)M_PI/(1.0f + (float)totin);
for(nsock= node->inputs.first; nsock; nsock= nsock->next) {
- if(!(nsock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL)) && (nsock->flag & SOCK_IN_USE)) {
+ if(!nodeSocketIsHidden(nsock)) {
nsock->locx= node->totr.xmin + hiddenrad + (float)sin(rad)*hiddenrad;
nsock->locy= node->totr.ymin + hiddenrad + (float)cos(rad)*hiddenrad;
rad+= drad;
@@ -713,7 +713,7 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
for(sock= node->inputs.first; sock; sock= sock->next) {
bNodeSocketType *stype= ntreeGetSocketType(sock->type);
- if(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))
+ if(nodeSocketIsHidden(sock))
continue;
node_socket_circle_draw(ntree, sock, NODE_SOCKSIZE);
@@ -736,7 +736,7 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
RNA_pointer_create((ID*)ntree, &RNA_NodeSocket, sock, &sockptr);
- if(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))
+ if(nodeSocketIsHidden(sock))
continue;
node_socket_circle_draw(ntree, sock, NODE_SOCKSIZE);
@@ -854,12 +854,12 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b
/* sockets */
for(sock= node->inputs.first; sock; sock= sock->next) {
- if(!(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL)) && (sock->flag & SOCK_IN_USE))
+ if(!nodeSocketIsHidden(sock))
node_socket_circle_draw(snode->nodetree, sock, socket_size);
}
for(sock= node->outputs.first; sock; sock= sock->next) {
- if(!(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL)) && (sock->flag & SOCK_IN_USE))
+ if(!nodeSocketIsHidden(sock))
node_socket_circle_draw(snode->nodetree, sock, socket_size);
}
diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c
index 87a56274035..20fb385efdd 100644
--- a/source/blender/editors/space_node/node_edit.c
+++ b/source/blender/editors/space_node/node_edit.c
@@ -1600,40 +1600,38 @@ void NODE_OT_resize(wmOperatorType *ot)
/* ********************** hidden sockets ******************** */
-int node_has_hidden_sockets(bNode *node)
+int node_has_hidden_sockets(bNode *node, short flag)
{
bNodeSocket *sock;
for(sock= node->inputs.first; sock; sock= sock->next)
- if(sock->flag & SOCK_HIDDEN)
+ if(sock->flag & flag)
return 1;
for(sock= node->outputs.first; sock; sock= sock->next)
- if(sock->flag & SOCK_HIDDEN)
+ if(sock->flag & flag)
return 1;
return 0;
}
-/* note: call node_tree_verify_groups(snode->nodetree) after this
- */
-void node_set_hidden_sockets(SpaceNode *snode, bNode *node, int set)
+void node_set_hidden_sockets(SpaceNode *snode, bNode *node, short flag, int set)
{
bNodeSocket *sock;
if(set==0) {
for(sock= node->inputs.first; sock; sock= sock->next)
- sock->flag &= ~SOCK_HIDDEN;
+ sock->flag &= ~flag;
for(sock= node->outputs.first; sock; sock= sock->next)
- sock->flag &= ~SOCK_HIDDEN;
+ sock->flag &= ~flag;
}
else {
/* hide unused sockets */
for(sock= node->inputs.first; sock; sock= sock->next) {
if(sock->link==NULL)
- sock->flag |= SOCK_HIDDEN;
+ sock->flag |= flag;
}
for(sock= node->outputs.first; sock; sock= sock->next) {
if(nodeCountSocketLinks(snode->edittree, sock)==0)
- sock->flag |= SOCK_HIDDEN;
+ sock->flag |= flag;
}
}
}
@@ -1680,14 +1678,14 @@ static void node_link_viewer(SpaceNode *snode, bNode *tonode)
/* find a socket after the previously connected socket */
for(sock=sock->next; sock; sock= sock->next)
- if(!(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL)))
+ if(!nodeSocketIsHidden(sock))
break;
}
/* find a socket starting from the first socket */
if(!sock) {
for(sock= tonode->outputs.first; sock; sock= sock->next)
- if(!(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL)))
+ if(!nodeSocketIsHidden(sock))
break;
}
@@ -1805,7 +1803,7 @@ static int find_indicated_socket(SpaceNode *snode, bNode **nodep, bNodeSocket **
if(in_out & SOCK_IN) {
for(sock= node->inputs.first; sock; sock= sock->next) {
- if(!(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) {
+ if(!nodeSocketIsHidden(sock)) {
if(BLI_in_rctf(&rect, sock->locx, sock->locy)) {
if(node == visible_node(snode, &rect)) {
*nodep= node;
@@ -1818,7 +1816,7 @@ static int find_indicated_socket(SpaceNode *snode, bNode **nodep, bNodeSocket **
}
if(in_out & SOCK_OUT) {
for(sock= node->outputs.first; sock; sock= sock->next) {
- if(!(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) {
+ if(!nodeSocketIsHidden(sock)) {
if(BLI_in_rctf(&rect, sock->locx, sock->locy)) {
if(node == visible_node(snode, &rect)) {
*nodep= node;
@@ -1836,7 +1834,7 @@ static int find_indicated_socket(SpaceNode *snode, bNode **nodep, bNodeSocket **
*/
if(in_out & SOCK_IN) {
for(sock= snode->edittree->outputs.first; sock; sock= sock->next) {
- if(!(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) {
+ if(!nodeSocketIsHidden(sock)) {
if(BLI_in_rctf(&rect, sock->locx, sock->locy)) {
*nodep= NULL; /* NULL node pointer indicates group socket */
*sockp= sock;
@@ -1847,7 +1845,7 @@ static int find_indicated_socket(SpaceNode *snode, bNode **nodep, bNodeSocket **
}
if(in_out & SOCK_OUT) {
for(sock= snode->edittree->inputs.first; sock; sock= sock->next) {
- if(!(sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))) {
+ if(!nodeSocketIsHidden(sock)) {
if(BLI_in_rctf(&rect, sock->locx, sock->locy)) {
*nodep= NULL; /* NULL node pointer indicates group socket */
*sockp= sock;
@@ -1930,13 +1928,12 @@ static int sort_nodes_locx(void *a, void *b)
static int socket_is_available(bNodeTree *ntree, bNodeSocket *sock, int allow_used)
{
- if (sock->flag & (SOCK_HIDDEN|SOCK_UNAVAIL))
+ if (nodeSocketIsHidden(sock))
+ return 0;
+
+ if (!allow_used && (sock->flag & SOCK_IN_USE))
return 0;
- if (!allow_used) {
- if (nodeCountSocketLinks(ntree, sock) > 0)
- return 0;
- }
return 1;
}
@@ -2246,7 +2243,7 @@ static void node_remove_extra_links(SpaceNode *snode, bNodeSocket *tsock, bNodeL
}
if(sock) {
tlink->tosock= sock;
- sock->flag &= ~SOCK_HIDDEN;
+ sock->flag &= ~(SOCK_HIDDEN|SOCK_AUTO_HIDDEN);
}
else {
nodeRemLink(snode->edittree, tlink);
@@ -2644,26 +2641,26 @@ static bNodeSocket *socket_best_match(ListBase *sockets, int type)
/* first, match type */
for(sock= sockets->first; sock; sock= sock->next)
- if(!(sock->flag & SOCK_HIDDEN))
+ if(!nodeSocketIsHidden(sock))
if(type == sock->type)
return sock;
/* then just use first unhidden socket */
for(sock= sockets->first; sock; sock= sock->next)
- if(!(sock->flag & SOCK_HIDDEN))
+ if(!nodeSocketIsHidden(sock))
return sock;
/* OK, let's unhide proper one */
for(sock= sockets->first; sock; sock= sock->next) {
if(type == sock->type) {
- sock->flag &= ~SOCK_HIDDEN;
+ sock->flag &= ~(SOCK_HIDDEN|SOCK_AUTO_HIDDEN);
return sock;
}
}
/* just the first */
sock= sockets->first;
- sock->flag &= ~SOCK_HIDDEN;
+ sock->flag &= ~(SOCK_HIDDEN|SOCK_AUTO_HIDDEN);
return sockets->first;
}
@@ -3003,10 +3000,20 @@ static void node_flag_toggle_exec(SpaceNode *snode, int toggle_flag)
if(toggle_flag== NODE_OPTIONS && (node->typeinfo->flag & NODE_OPTIONS)==0)
continue;
- if( (tot_eq && tot_neq) || tot_eq==0)
+ if( (tot_eq && tot_neq) || tot_eq==0) {
node->flag |= toggle_flag;
- else
+
+ /* hide/unhide node also toggles unlinked socket display */
+ if (toggle_flag== NODE_HIDDEN)
+ node_set_hidden_sockets(snode, node, SOCK_AUTO_HIDDEN, 1);
+ }
+ else {
node->flag &= ~toggle_flag;
+
+ /* hide/unhide node also toggles unlinked socket display */
+ if (toggle_flag== NODE_HIDDEN)
+ node_set_hidden_sockets(snode, node, SOCK_AUTO_HIDDEN, 0);
+ }
}
}
}
@@ -3119,7 +3126,7 @@ static int node_socket_toggle_exec(bContext *C, wmOperator *UNUSED(op))
hidden = 0;
for(node= snode->edittree->nodes.first; node; node= node->next) {
if(node->flag & SELECT) {
- if(node_has_hidden_sockets(node)) {
+ if(node_has_hidden_sockets(node, SOCK_HIDDEN)) {
hidden= 1;
break;
}
@@ -3128,7 +3135,7 @@ static int node_socket_toggle_exec(bContext *C, wmOperator *UNUSED(op))
for(node= snode->edittree->nodes.first; node; node= node->next) {
if(node->flag & SELECT) {
- node_set_hidden_sockets(snode, node, !hidden);
+ node_set_hidden_sockets(snode, node, SOCK_HIDDEN, !hidden);
}
}
diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h
index 9068493360e..186ad3768be 100644
--- a/source/blender/editors/space_node/node_intern.h
+++ b/source/blender/editors/space_node/node_intern.h
@@ -118,8 +118,8 @@ void snode_composite_job(const struct bContext *C, ScrArea *sa);
bNode *node_tree_get_editgroup(bNodeTree *ntree);
void node_tree_verify_groups(bNodeTree *nodetree);
void snode_autoconnect(SpaceNode *snode, int allow_multiple, int replace);
-int node_has_hidden_sockets(bNode *node);
-void node_set_hidden_sockets(SpaceNode *snode, bNode *node, int set);
+int node_has_hidden_sockets(bNode *node, short flag);
+void node_set_hidden_sockets(SpaceNode *snode, bNode *node, short flag, int set);
int node_render_changed_exec(bContext *, wmOperator *);
void NODE_OT_duplicate(struct wmOperatorType *ot);
diff --git a/source/blender/editors/space_node/node_templates.c b/source/blender/editors/space_node/node_templates.c
index 6027a272270..a733d45c20b 100644
--- a/source/blender/editors/space_node/node_templates.c
+++ b/source/blender/editors/space_node/node_templates.c
@@ -1,6 +1,4 @@
/*
- * $Id$
- *
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c
index 5fd3d3b45d6..56c2e0ee4d1 100644
--- a/source/blender/editors/space_sequencer/sequencer_edit.c
+++ b/source/blender/editors/space_sequencer/sequencer_edit.c
@@ -2711,8 +2711,8 @@ static int sequencer_swap_data_exec(bContext *C, wmOperator *op)
calc_sequence(scene, seq_act);
calc_sequence(scene, seq_other);
- if(seq_act->sound) sound_add_scene_sound(scene, seq_act, seq_act->startdisp, seq_act->enddisp, seq_act->startofs + seq_act->anim_startofs);
- if(seq_other->sound) sound_add_scene_sound(scene, seq_other, seq_other->startdisp, seq_other->enddisp, seq_other->startofs + seq_other->anim_startofs);
+ if(seq_act->sound) sound_add_scene_sound_defaults(scene, seq_act);
+ if(seq_other->sound) sound_add_scene_sound_defaults(scene, seq_other);
WM_event_add_notifier(C, NC_SCENE|ND_SEQUENCER, scene);
diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c
index ad2a0da4510..6bc1b3acce6 100644
--- a/source/blender/editors/space_view3d/view3d_snap.c
+++ b/source/blender/editors/space_view3d/view3d_snap.c
@@ -768,8 +768,7 @@ static void bundle_midpoint(Scene *scene, Object *ob, float vec[3])
tracking= &clip->tracking;
- if(scene->camera)
- copy_m4_m4(cammat, scene->camera->obmat);
+ copy_m4_m4(cammat, ob->obmat);
BKE_get_tracking_mat(scene, ob, mat);
diff --git a/source/blender/gpu/GPU_buffers.h b/source/blender/gpu/GPU_buffers.h
index 9e551f637de..a72c79a1e62 100644
--- a/source/blender/gpu/GPU_buffers.h
+++ b/source/blender/gpu/GPU_buffers.h
@@ -167,7 +167,7 @@ void GPU_update_mesh_buffers(GPU_Buffers *buffers, struct MVert *mvert,
int *vert_indices, int totvert);
GPU_Buffers *GPU_build_grid_buffers(struct DMGridData **grids,
int *grid_indices, int totgrid, int gridsize);
-void GPU_update_grid_buffers(GPU_Buffers *buffers_v, struct DMGridData **grids,
+void GPU_update_grid_buffers(GPU_Buffers *buffers, struct DMGridData **grids,
int *grid_indices, int totgrid, int gridsize, int smooth);
void GPU_draw_buffers(GPU_Buffers *buffers);
void GPU_free_buffers(GPU_Buffers *buffers);
diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c
index 919dc3f6403..99dd3987937 100644
--- a/source/blender/gpu/intern/gpu_buffers.c
+++ b/source/blender/gpu/intern/gpu_buffers.c
@@ -1296,10 +1296,9 @@ struct GPU_Buffers {
unsigned int tot_tri, tot_quad;
};
-void GPU_update_mesh_buffers(GPU_Buffers *buffers_v, MVert *mvert,
+void GPU_update_mesh_buffers(GPU_Buffers *buffers, MVert *mvert,
int *vert_indices, int totvert)
{
- GPU_Buffers *buffers = buffers_v;
VertexBufferFormat *vert_data;
int i;
@@ -1413,10 +1412,9 @@ GPU_Buffers *GPU_build_mesh_buffers(GHash *map, MVert *mvert, MFace *mface,
return buffers;
}
-void GPU_update_grid_buffers(GPU_Buffers *buffers_v, DMGridData **grids,
+void GPU_update_grid_buffers(GPU_Buffers *buffers, DMGridData **grids,
int *grid_indices, int totgrid, int gridsize, int smooth)
{
- GPU_Buffers *buffers = buffers_v;
DMGridData *vert_data;
int i, j, k, totvert;
@@ -1465,7 +1463,7 @@ void GPU_update_grid_buffers(GPU_Buffers *buffers_v, DMGridData **grids,
buffers->totgrid = totgrid;
buffers->gridsize = gridsize;
- //printf("node updated %p\n", buffers_v);
+ //printf("node updated %p\n", buffers);
}
GPU_Buffers *GPU_build_grid_buffers(DMGridData **UNUSED(grids), int *UNUSED(grid_indices),
@@ -1558,10 +1556,8 @@ GPU_Buffers *GPU_build_grid_buffers(DMGridData **UNUSED(grids), int *UNUSED(grid
return buffers;
}
-void GPU_draw_buffers(GPU_Buffers *buffers_v)
+void GPU_draw_buffers(GPU_Buffers *buffers)
{
- GPU_Buffers *buffers = buffers_v;
-
if(buffers->vert_buf && buffers->index_buf) {
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
@@ -1632,11 +1628,9 @@ void GPU_draw_buffers(GPU_Buffers *buffers_v)
}
}
-void GPU_free_buffers(GPU_Buffers *buffers_v)
+void GPU_free_buffers(GPU_Buffers *buffers)
{
- if(buffers_v) {
- GPU_Buffers *buffers = buffers_v;
-
+ if(buffers) {
if(buffers->vert_buf)
glDeleteBuffersARB(1, &buffers->vert_buf);
if(buffers->index_buf)
@@ -1645,4 +1639,3 @@ void GPU_free_buffers(GPU_Buffers *buffers_v)
MEM_freeN(buffers);
}
}
-
diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c
index fb1d10b5491..93ea067cfb7 100644
--- a/source/blender/gpu/intern/gpu_material.c
+++ b/source/blender/gpu/intern/gpu_material.c
@@ -1120,7 +1120,11 @@ static void do_material_tex(GPUShadeInput *shi)
// to inverting the bump map. Should this ever change
// this negate must be removed.
norfac = -hScale * mtex->norfac;
- if(found_deriv_map) norfac /= sqrtf(ima_x*ima_y);
+ if(found_deriv_map)
+ {
+ float fVirtDim = sqrtf(fabsf(ima_x*mtex->size[0]*ima_y*mtex->size[1]));
+ norfac /= MAX2(fVirtDim, FLT_EPSILON);
+ }
tnorfac = GPU_uniform(&norfac);
diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h
index 7f99fc3ffc7..996bfd35581 100644
--- a/source/blender/imbuf/IMB_imbuf.h
+++ b/source/blender/imbuf/IMB_imbuf.h
@@ -380,7 +380,7 @@ void IMB_color_to_bw(struct ImBuf *ibuf);
/* converting pixel buffers */
void IMB_buffer_byte_from_float(unsigned char *rect_to, const float *rect_from,
- int channels_from, int dither, int profile_to, int profile_from, int predivide,
+ int channels_from, float dither, int profile_to, int profile_from, int predivide,
int width, int height, int stride_to, int stride_from);
void IMB_buffer_float_from_byte(float *rect_to, const unsigned char *rect_from,
int profile_to, int profile_from, int predivide,
@@ -426,14 +426,6 @@ void bilinear_interpolation_color_wrap(struct ImBuf *in, unsigned char *col, flo
* @attention defined in readimage.c
* @deprecated Only here for backwards compatibility of the
* @deprecated plugin system.
- */
-struct ImBuf *IMB_loadiffmem(int *mem, int flags);
-
-/**
- *
- * @attention defined in readimage.c
- * @deprecated Only here for backwards compatibility of the
- * @deprecated plugin system.
*/
struct ImBuf *IMB_loadifffile(int file, int flags, const char *descr);
diff --git a/source/blender/imbuf/intern/anim_movie.c b/source/blender/imbuf/intern/anim_movie.c
index 45264fa862b..e6d09285685 100644
--- a/source/blender/imbuf/intern/anim_movie.c
+++ b/source/blender/imbuf/intern/anim_movie.c
@@ -768,8 +768,8 @@ static int ffmpeg_decode_video_frame(struct anim * anim)
== AV_NOPTS_VALUE) ?
-1 : (long long int)anim->pFrame->pkt_pts,
(long long int)anim->next_pts);
+ break;
}
- break;
}
av_free_packet(&anim->next_packet);
anim->next_packet.stream_index = -1;
diff --git a/source/blender/imbuf/intern/divers.c b/source/blender/imbuf/intern/divers.c
index 0dfc1852e29..034b5724ca6 100644
--- a/source/blender/imbuf/intern/divers.c
+++ b/source/blender/imbuf/intern/divers.c
@@ -123,7 +123,7 @@ MINLINE void float_to_byte_dither_v4(uchar b[4], const float f[4], float dither)
/* float to byte pixels, output 4-channel RGBA */
void IMB_buffer_byte_from_float(uchar *rect_to, const float *rect_from,
- int channels_from, int dither, int profile_to, int profile_from, int predivide,
+ int channels_from, float dither, int profile_to, int profile_from, int predivide,
int width, int height, int stride_to, int stride_from)
{
float tmp[4];
diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h
index 8fdbde60bab..c829d5be294 100644
--- a/source/blender/makesdna/DNA_constraint_types.h
+++ b/source/blender/makesdna/DNA_constraint_types.h
@@ -417,6 +417,7 @@ typedef struct bFollowTrackConstraint {
int flag, pad;
char object[24];
struct Object *camera;
+ struct Object *depth_ob;
} bFollowTrackConstraint;
/* Camera Solver constraints */
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index 5fe9851738a..77fa03aeedc 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -313,13 +313,13 @@ typedef struct DisplaceModifierData {
char uvlayer_name[32];
int uvlayer_tmp;
int texmapping;
- int pad10;
/* end MappingInfoModifierData */
float strength;
int direction;
char defgrp_name[32];
float midlevel;
+ int pad;
} DisplaceModifierData;
/* DisplaceModifierData->direction */
@@ -336,7 +336,7 @@ enum {
MOD_DISP_MAP_LOCAL,
MOD_DISP_MAP_GLOBAL,
MOD_DISP_MAP_OBJECT,
- MOD_DISP_MAP_UV,
+ MOD_DISP_MAP_UV
};
typedef struct UVProjectModifierData {
@@ -401,13 +401,6 @@ typedef struct CastModifierData {
short flag, type;
} CastModifierData;
-enum {
- MOD_WAV_MAP_LOCAL,
- MOD_WAV_MAP_GLOBAL,
- MOD_WAV_MAP_OBJECT,
- MOD_WAV_MAP_UV,
-};
-
/* WaveModifierData.flag */
#define MOD_WAVE_X (1<<1)
#define MOD_WAVE_Y (1<<2)
@@ -420,20 +413,22 @@ enum {
typedef struct WaveModifierData {
ModifierData modifier;
- struct Object *objectcenter;
- char defgrp_name[32];
+ /* keep in sync with MappingInfoModifierData */
struct Tex *texture;
struct Object *map_object;
+ char uvlayer_name[32];
+ int uvlayer_tmp;
+ int texmapping;
+ /* end MappingInfoModifierData */
+
+ struct Object *objectcenter;
+ char defgrp_name[32];
short flag, pad;
float startx, starty, height, width;
float narrow, speed, damp, falloff;
- int texmapping, uvlayer_tmp;
-
- char uvlayer_name[32];
-
float timeoffs, lifetime;
float pad1;
} WaveModifierData;
@@ -822,19 +817,17 @@ typedef struct WarpModifierData {
char uvlayer_name[32];
int uvlayer_tmp;
int texmapping;
- int pad10;
/* end MappingInfoModifierData */
- float strength;
-
struct Object *object_from;
struct Object *object_to;
struct CurveMapping *curfalloff;
char defgrp_name[32]; /* optional vertexgroup name */
+ float strength;
float falloff_radius;
char flag; /* not used yet */
char falloff_type;
- char pad[2];
+ char pad[6];
} WarpModifierData;
#define MOD_WARP_VOLUME_PRESERVE 1
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index aa9b43584fd..e2d612169e7 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -129,6 +129,8 @@ typedef struct bNodeSocket {
#define SOCK_COLLAPSED 64
/* hide socket value, if it gets auto default */
#define SOCK_HIDE_VALUE 128
+ /* socket hidden automatically, to distinguish from manually hidden */
+#define SOCK_AUTO_HIDDEN 256
typedef struct bNodePreview {
unsigned char *rect;
diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h
index bff1c214b4f..a6e3d16a5f5 100644
--- a/source/blender/makesrna/RNA_access.h
+++ b/source/blender/makesrna/RNA_access.h
@@ -615,9 +615,9 @@ extern StructRNA RNA_VoxelData;
extern StructRNA RNA_VoxelDataTexture;
extern StructRNA RNA_WarpModifier;
extern StructRNA RNA_WaveModifier;
-extern StructRNA RNA_WeightVGEditModifier;
-extern StructRNA RNA_WeightVGMixModifier;
-extern StructRNA RNA_WeightVGProximityModifier;
+extern StructRNA RNA_VertexWeightEditModifier;
+extern StructRNA RNA_VertexWeightMixModifier;
+extern StructRNA RNA_VertexWeightProximityModifier;
extern StructRNA RNA_Window;
extern StructRNA RNA_WindowManager;
extern StructRNA RNA_WipeSequence;
diff --git a/source/blender/makesrna/RNA_enum_types.h b/source/blender/makesrna/RNA_enum_types.h
index fb6e2544296..7daa92b1788 100644
--- a/source/blender/makesrna/RNA_enum_types.h
+++ b/source/blender/makesrna/RNA_enum_types.h
@@ -104,6 +104,8 @@ extern EnumPropertyItem property_type_items[];
extern EnumPropertyItem property_subtype_items[];
extern EnumPropertyItem property_unit_items[];
+extern EnumPropertyItem gameproperty_type_items[];
+
extern EnumPropertyItem viewport_shade_items[];
extern EnumPropertyItem nodetree_type_items[];
diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c
index dc6b7e4d456..70bc8254476 100644
--- a/source/blender/makesrna/intern/makesrna.c
+++ b/source/blender/makesrna/intern/makesrna.c
@@ -43,9 +43,14 @@
#define RNA_VERSION_DATE "FIXME-RNA_VERSION_DATE"
#ifdef _WIN32
-#ifndef snprintf
-#define snprintf _snprintf
+# ifndef snprintf
+# define snprintf _snprintf
+# endif
#endif
+
+/* so we can use __func__ everywhere */
+#if defined(_MSC_VER)
+# define __func__ __FUNCTION__
#endif
/* Replace if different */
@@ -448,11 +453,9 @@ static int rna_enum_bitmask(PropertyRNA *prop)
static int rna_color_quantize(PropertyRNA *prop, PropertyDefRNA *dp)
{
- if(prop->type == PROP_FLOAT && (prop->subtype==PROP_COLOR || prop->subtype==PROP_COLOR_GAMMA))
- if(strcmp(dp->dnatype, "float") != 0 && strcmp(dp->dnatype, "double") != 0)
- return 1;
-
- return 0;
+ return ( (prop->type == PROP_FLOAT) &&
+ (prop->subtype==PROP_COLOR || prop->subtype==PROP_COLOR_GAMMA) &&
+ (IS_DNATYPE_FLOAT_COMPAT(dp->dnatype) == 0) );
}
static const char *rna_function_string(void *func)
@@ -484,7 +487,8 @@ static char *rna_def_property_get_func(FILE *f, StructRNA *srna, PropertyRNA *pr
if(!manualfunc) {
if(!dp->dnastructname || !dp->dnaname) {
- fprintf(stderr, "rna_def_property_get_func: %s.%s has no valid dna info.\n", srna->identifier, prop->identifier);
+ fprintf(stderr, "%s (0): %s.%s has no valid dna info.\n",
+ __func__, srna->identifier, prop->identifier);
DefRNA.error= 1;
return NULL;
}
@@ -495,7 +499,8 @@ static char *rna_def_property_get_func(FILE *f, StructRNA *srna, PropertyRNA *pr
if(prop->type == PROP_FLOAT) {
if(IS_DNATYPE_FLOAT_COMPAT(dp->dnatype) == 0) {
if(prop->subtype != PROP_COLOR_GAMMA) { /* colors are an exception. these get translated */
- fprintf(stderr, "rna_def_property_get_func1: %s.%s is a '%s' but wrapped as type '%s'.\n", srna->identifier, prop->identifier, dp->dnatype, RNA_property_typename(prop->type));
+ fprintf(stderr, "%s (1): %s.%s is a '%s' but wrapped as type '%s'.\n",
+ __func__, srna->identifier, prop->identifier, dp->dnatype, RNA_property_typename(prop->type));
DefRNA.error= 1;
return NULL;
}
@@ -503,7 +508,8 @@ static char *rna_def_property_get_func(FILE *f, StructRNA *srna, PropertyRNA *pr
}
else if(prop->type == PROP_INT || prop->type == PROP_BOOLEAN || prop->type == PROP_ENUM) {
if(IS_DNATYPE_INT_COMPAT(dp->dnatype) == 0) {
- fprintf(stderr, "rna_def_property_get_func2: %s.%s is a '%s' but wrapped as type '%s'.\n", srna->identifier, prop->identifier, dp->dnatype, RNA_property_typename(prop->type));
+ fprintf(stderr, "%s (2): %s.%s is a '%s' but wrapped as type '%s'.\n",
+ __func__, srna->identifier, prop->identifier, dp->dnatype, RNA_property_typename(prop->type));
DefRNA.error= 1;
return NULL;
}
@@ -724,7 +730,8 @@ static char *rna_def_property_set_func(FILE *f, StructRNA *srna, PropertyRNA *pr
if(!manualfunc) {
if(!dp->dnastructname || !dp->dnaname) {
if(prop->flag & PROP_EDITABLE) {
- fprintf(stderr, "rna_def_property_set_func: %s.%s has no valid dna info.\n", srna->identifier, prop->identifier);
+ fprintf(stderr, "%s: %s.%s has no valid dna info.\n",
+ __func__, srna->identifier, prop->identifier);
DefRNA.error= 1;
}
return NULL;
@@ -902,7 +909,8 @@ static char *rna_def_property_length_func(FILE *f, StructRNA *srna, PropertyRNA
if(prop->type == PROP_STRING) {
if(!manualfunc) {
if(!dp->dnastructname || !dp->dnaname) {
- fprintf(stderr, "rna_def_property_length_func: %s.%s has no valid dna info.\n", srna->identifier, prop->identifier);
+ fprintf(stderr, "%s: %s.%s has no valid dna info.\n",
+ __func__, srna->identifier, prop->identifier);
DefRNA.error= 1;
return NULL;
}
@@ -924,7 +932,8 @@ static char *rna_def_property_length_func(FILE *f, StructRNA *srna, PropertyRNA
else if(prop->type == PROP_COLLECTION) {
if(!manualfunc) {
if(prop->type == PROP_COLLECTION && (!(dp->dnalengthname || dp->dnalengthfixed)|| !dp->dnaname)) {
- fprintf(stderr, "rna_def_property_length_func: %s.%s has no valid dna info.\n", srna->identifier, prop->identifier);
+ fprintf(stderr, "%s: %s.%s has no valid dna info.\n",
+ __func__, srna->identifier, prop->identifier);
DefRNA.error= 1;
return NULL;
}
@@ -959,7 +968,8 @@ static char *rna_def_property_begin_func(FILE *f, StructRNA *srna, PropertyRNA *
if(!manualfunc) {
if(!dp->dnastructname || !dp->dnaname) {
- fprintf(stderr, "rna_def_property_begin_func: %s.%s has no valid dna info.\n", srna->identifier, prop->identifier);
+ fprintf(stderr, "%s: %s.%s has no valid dna info.\n",
+ __func__, srna->identifier, prop->identifier);
DefRNA.error= 1;
return NULL;
}
@@ -1270,7 +1280,8 @@ static void rna_def_property_funcs(FILE *f, StructRNA *srna, PropertyDefRNA *dp)
pprop->get= (void*)rna_def_property_get_func(f, srna, prop, dp, (const char*)pprop->get);
pprop->set= (void*)rna_def_property_set_func(f, srna, prop, dp, (const char*)pprop->set);
if(!pprop->type) {
- fprintf(stderr, "rna_def_property_funcs: %s.%s, pointer must have a struct type.\n", srna->identifier, prop->identifier);
+ fprintf(stderr, "%s: %s.%s, pointer must have a struct type.\n",
+ __func__, srna->identifier, prop->identifier);
DefRNA.error= 1;
}
break;
@@ -1298,20 +1309,24 @@ static void rna_def_property_funcs(FILE *f, StructRNA *srna, PropertyDefRNA *dp)
if(!(prop->flag & PROP_IDPROPERTY)) {
if(!cprop->begin) {
- fprintf(stderr, "rna_def_property_funcs: %s.%s, collection must have a begin function.\n", srna->identifier, prop->identifier);
+ fprintf(stderr, "%s: %s.%s, collection must have a begin function.\n",
+ __func__, srna->identifier, prop->identifier);
DefRNA.error= 1;
}
if(!cprop->next) {
- fprintf(stderr, "rna_def_property_funcs: %s.%s, collection must have a next function.\n", srna->identifier, prop->identifier);
+ fprintf(stderr, "%s: %s.%s, collection must have a next function.\n",
+ __func__, srna->identifier, prop->identifier);
DefRNA.error= 1;
}
if(!cprop->get) {
- fprintf(stderr, "rna_def_property_funcs: %s.%s, collection must have a get function.\n", srna->identifier, prop->identifier);
+ fprintf(stderr, "%s: %s.%s, collection must have a get function.\n",
+ __func__, srna->identifier, prop->identifier);
DefRNA.error= 1;
}
}
if(!cprop->item_type) {
- fprintf(stderr, "rna_def_property_funcs: %s.%s, collection must have a struct type.\n", srna->identifier, prop->identifier);
+ fprintf(stderr, "%s: %s.%s, collection must have a struct type.\n",
+ __func__, srna->identifier, prop->identifier);
DefRNA.error= 1;
}
break;
@@ -2136,19 +2151,22 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr
if(prop->flag & PROP_ENUM_FLAG) {
if(eprop->defaultvalue & ~totflag) {
- fprintf(stderr, "rna_generate_structs: %s%s.%s, enum default includes unused bits (%d).\n", srna->identifier, errnest, prop->identifier, eprop->defaultvalue & ~totflag);
+ fprintf(stderr, "%s: %s%s.%s, enum default includes unused bits (%d).\n",
+ __func__, srna->identifier, errnest, prop->identifier, eprop->defaultvalue & ~totflag);
DefRNA.error= 1;
}
}
else {
if(!defaultfound) {
- fprintf(stderr, "rna_generate_structs: %s%s.%s, enum default is not in items.\n", srna->identifier, errnest, prop->identifier);
+ fprintf(stderr, "%s: %s%s.%s, enum default is not in items.\n",
+ __func__, srna->identifier, errnest, prop->identifier);
DefRNA.error= 1;
}
}
}
else {
- fprintf(stderr, "rna_generate_structs: %s%s.%s, enum must have items defined.\n", srna->identifier, errnest, prop->identifier);
+ fprintf(stderr, "%s: %s%s.%s, enum must have items defined.\n",
+ __func__, srna->identifier, errnest, prop->identifier);
DefRNA.error= 1;
}
break;
@@ -2262,7 +2280,7 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr
if(prop->arraydimension && prop->totarraylength) fprintf(f, "rna_%s%s_%s_default\n", srna->identifier, strnest, prop->identifier);
else fprintf(f, "NULL\n");
break;
- }
+ }
case PROP_FLOAT: {
FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
fprintf(f, "\t%s, %s, %s, %s, %s, ", rna_function_string(fprop->get), rna_function_string(fprop->set), rna_function_string(fprop->getarray), rna_function_string(fprop->setarray), rna_function_string(fprop->range));
@@ -2276,7 +2294,7 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr
if(prop->arraydimension && prop->totarraylength) fprintf(f, "rna_%s%s_%s_default\n", srna->identifier, strnest, prop->identifier);
else fprintf(f, "NULL\n");
break;
- }
+ }
case PROP_STRING: {
StringPropertyRNA *sprop= (StringPropertyRNA*)prop;
fprintf(f, "\t%s, %s, %s, %d, ", rna_function_string(sprop->get), rna_function_string(sprop->length), rna_function_string(sprop->set), sprop->maxlength);
@@ -2299,7 +2317,7 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr
if(pprop->type) fprintf(f, "&RNA_%s\n", (const char*)pprop->type);
else fprintf(f, "NULL\n");
break;
- }
+ }
case PROP_COLLECTION: {
CollectionPropertyRNA *cprop= (CollectionPropertyRNA*)prop;
fprintf(f, "\t%s, %s, %s, %s, %s, %s, %s, %s, ", rna_function_string(cprop->begin), rna_function_string(cprop->next), rna_function_string(cprop->end), rna_function_string(cprop->get), rna_function_string(cprop->length), rna_function_string(cprop->lookupint), rna_function_string(cprop->lookupstring), rna_function_string(cprop->assignint));
@@ -2421,7 +2439,8 @@ static void rna_generate_struct(BlenderRNA *brna, StructRNA *srna, FILE *f)
fprintf(f, "\t%s,\n", rna_function_string(srna->idproperties));
if(srna->reg && !srna->refine) {
- fprintf(stderr, "rna_generate_struct: %s has a register function, must also have refine function.\n", srna->identifier);
+ fprintf(stderr, "%s: %s has a register function, must also have refine function.\n",
+ __func__, srna->identifier);
DefRNA.error= 1;
}
@@ -2631,6 +2650,7 @@ static void rna_generate_header(BlenderRNA *brna, FILE *f)
static const char *cpp_classes = ""
"\n"
"#include <string>\n"
+"#include <string.h> /* for memcpy */\n"
"\n"
"namespace BL {\n"
"\n"
@@ -2756,6 +2776,7 @@ static void rna_generate_header_cpp(BlenderRNA *brna, FILE *f)
fprintf(f, "#include \"RNA_blender.h\"\n");
fprintf(f, "#include \"RNA_types.h\"\n");
+ fprintf(f, "#include \"RNA_access.h\"\n");
fprintf(f, "%s", cpp_classes);
@@ -2842,7 +2863,7 @@ static int rna_preprocess(const char *outfile)
file = fopen(deffile, "w");
if(!file) {
- printf ("Unable to open file: %s\n", deffile);
+ fprintf(stderr, "Unable to open file: %s\n", deffile);
status = 1;
}
else {
@@ -2870,7 +2891,7 @@ static int rna_preprocess(const char *outfile)
file = fopen(deffile, "w");
if(!file) {
- printf ("Unable to open file: %s\n", deffile);
+ fprintf(stderr, "Unable to open file: %s\n", deffile);
status = 1;
}
else {
@@ -2899,7 +2920,7 @@ static int rna_preprocess(const char *outfile)
file = fopen(deffile, "w");
if(!file) {
- printf ("Unable to open file: %s\n", deffile);
+ fprintf(stderr, "Unable to open file: %s\n", deffile);
status = 1;
}
else {
@@ -2929,18 +2950,18 @@ int main(int argc, char **argv)
int totblock, return_status = 0;
if(argc<2) {
- printf("Usage: %s outdirectory/\n", argv[0]);
+ fprintf(stderr, "Usage: %s outdirectory/\n", argv[0]);
return_status = 1;
}
else {
- printf("Running makesrna, program versions %s\n", RNA_VERSION_DATE);
+ fprintf(stderr, "Running makesrna, program versions %s\n", RNA_VERSION_DATE);
makesrna_path= argv[0];
return_status= rna_preprocess(argv[1]);
}
totblock= MEM_get_memory_blocks_in_use();
if(totblock!=0) {
- printf("Error Totblock: %d\n",totblock);
+ fprintf(stderr, "Error Totblock: %d\n",totblock);
MEM_set_error_callback(mem_error_cb);
MEM_printmemlist();
}
diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c
index 6439d22e808..3258b8c3dcb 100644
--- a/source/blender/makesrna/intern/rna_constraint.c
+++ b/source/blender/makesrna/intern/rna_constraint.c
@@ -358,6 +358,34 @@ static void rna_Constraint_followTrack_camera_set(PointerRNA *ptr, PointerRNA va
}
}
+static void rna_Constraint_followTrack_depthObject_set(PointerRNA *ptr, PointerRNA value)
+{
+ bConstraint *con= (bConstraint*)ptr->data;
+ bFollowTrackConstraint *data= (bFollowTrackConstraint*)con->data;
+ Object *ob= (Object*)value.data;
+
+ if (ob) {
+ if (ob->type == OB_MESH && ob != (Object*)ptr->id.data) {
+ data->depth_ob= ob;
+ }
+ } else {
+ data->depth_ob= NULL;
+ }
+}
+
+static int rna_Constraint_followTrack_depthObject_poll(PointerRNA *ptr, PointerRNA value)
+{
+ Object *ob= (Object*)value.data;
+
+ if(ob) {
+ if (ob->type == OB_MESH && ob != (Object*)ptr->id.data) {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
static void rna_Constraint_objectSolver_camera_set(PointerRNA *ptr, PointerRNA value)
{
bConstraint *con= (bConstraint*)ptr->data;
@@ -2126,6 +2154,14 @@ static void rna_def_constraint_follow_track(BlenderRNA *brna)
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_dependency_update");
RNA_def_property_pointer_funcs(prop, NULL, "rna_Constraint_followTrack_camera_set", NULL, "rna_Constraint_cameraObject_poll");
+
+ /* depth object */
+ prop= RNA_def_property(srna, "depth_object", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "depth_ob");
+ RNA_def_property_ui_text(prop, "Depth Object", "Object used to define depth in camera space by projecting onto surface of this object");
+ RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_dependency_update");
+ RNA_def_property_pointer_funcs(prop, NULL, "rna_Constraint_followTrack_depthObject_set", NULL, "rna_Constraint_followTrack_depthObject_poll");
}
static void rna_def_constraint_camera_solver(BlenderRNA *brna)
diff --git a/source/blender/makesrna/intern/rna_define.c b/source/blender/makesrna/intern/rna_define.c
index caf43793996..53944f7ec5c 100644
--- a/source/blender/makesrna/intern/rna_define.c
+++ b/source/blender/makesrna/intern/rna_define.c
@@ -1628,6 +1628,7 @@ void RNA_def_property_int_sdna(PropertyRNA *prop, const char *structname, const
void RNA_def_property_float_sdna(PropertyRNA *prop, const char *structname, const char *propname)
{
PropertyDefRNA *dp;
+ FloatPropertyRNA *fprop= (FloatPropertyRNA*)prop;
StructRNA *srna= DefRNA.laststruct;
if(!DefRNA.preprocess) {
@@ -1652,6 +1653,11 @@ void RNA_def_property_float_sdna(PropertyRNA *prop, const char *structname, cons
}
}
}
+
+ if(dp->dnatype && strcmp(dp->dnatype, "char") == 0) {
+ fprop->hardmin= fprop->softmin= 0.0f;
+ fprop->hardmax= fprop->softmax= 1.0f;
+ }
}
rna_def_property_sdna(prop, structname, propname);
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index 9474c572d88..3a7d453fa79 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -452,12 +452,6 @@ static void RNA_WarpModifier_vgroup_set(PointerRNA *ptr, const char *value)
rna_object_vgroup_name_set(ptr, value, tmd->defgrp_name, sizeof(tmd->defgrp_name));
}
-static void rna_WaveModifier_uvlayer_set(PointerRNA *ptr, const char *value)
-{
- WaveModifierData *wmd= (WaveModifierData*)ptr->data;
- rna_object_uvlayer_name_set(ptr, value, wmd->uvlayer_name, sizeof(wmd->uvlayer_name));
-}
-
static void rna_WeightVGModifier_mask_uvlayer_set(PointerRNA *ptr, const char *value)
{
ModifierData *md = (ModifierData*)ptr->data;
@@ -1125,13 +1119,6 @@ static void rna_def_modifier_wave(BlenderRNA *brna)
StructRNA *srna;
PropertyRNA *prop;
- static EnumPropertyItem prop_texture_coordinates_items[] = {
- {MOD_WAV_MAP_LOCAL, "LOCAL", 0, "Local", ""},
- {MOD_WAV_MAP_GLOBAL, "GLOBAL", 0, "Global", ""},
- {MOD_WAV_MAP_OBJECT, "OBJECT", 0, "Object", ""},
- {MOD_WAV_MAP_UV, "MAP_UV", 0, "UV", ""},
- {0, NULL, 0, NULL, NULL}};
-
srna= RNA_def_struct(brna, "WaveModifier", "Modifier");
RNA_def_struct_ui_text(srna, "Wave Modifier", "Wave effect modifier");
RNA_def_struct_sdna(srna, "WaveModifierData");
@@ -1223,29 +1210,6 @@ static void rna_def_modifier_wave(BlenderRNA *brna)
RNA_def_property_string_funcs(prop, NULL, NULL, "rna_WaveModifier_vgroup_set");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
- prop= RNA_def_property(srna, "texture", PROP_POINTER, PROP_NONE);
- RNA_def_property_ui_text(prop, "Texture", "Texture for modulating the wave");
- RNA_def_property_flag(prop, PROP_EDITABLE);
- RNA_def_property_update(prop, 0, "rna_Modifier_update");
-
- prop= RNA_def_property(srna, "texture_coords", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_sdna(prop, NULL, "texmapping");
- RNA_def_property_enum_items(prop, prop_texture_coordinates_items);
- RNA_def_property_ui_text(prop, "Texture Coordinates", "Texture coordinates used for modulating input");
- RNA_def_property_update(prop, 0, "rna_Modifier_update");
-
- prop= RNA_def_property(srna, "uv_layer", PROP_STRING, PROP_NONE);
- RNA_def_property_string_sdna(prop, NULL, "uvlayer_name");
- RNA_def_property_ui_text(prop, "UV Map", "UV map name");
- RNA_def_property_string_funcs(prop, NULL, NULL, "rna_WaveModifier_uvlayer_set");
- RNA_def_property_update(prop, 0, "rna_Modifier_update");
-
- prop= RNA_def_property(srna, "texture_coords_object", PROP_POINTER, PROP_NONE);
- RNA_def_property_pointer_sdna(prop, NULL, "map_object");
- RNA_def_property_ui_text(prop, "Texture Coordinates Object", "");
- RNA_def_property_flag(prop, PROP_EDITABLE|PROP_ID_SELF_CHECK);
- RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update");
-
prop= RNA_def_property(srna, "speed", PROP_FLOAT, PROP_NONE);
RNA_def_property_range(prop, -FLT_MAX, FLT_MAX);
RNA_def_property_ui_range(prop, -1, 1, 10, 2);
@@ -1270,6 +1234,8 @@ static void rna_def_modifier_wave(BlenderRNA *brna)
RNA_def_property_ui_range(prop, 0, 10, 10, 2);
RNA_def_property_ui_text(prop, "Narrowness", "Distance between the top and the base of a wave, the higher the value, the more narrow the wave");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ rna_def_modifier_generic_map_info(srna);
}
static void rna_def_modifier_armature(BlenderRNA *brna)
diff --git a/source/blender/makesrna/intern/rna_property.c b/source/blender/makesrna/intern/rna_property.c
index e8ef61b6d74..dfdc175d18b 100644
--- a/source/blender/makesrna/intern/rna_property.c
+++ b/source/blender/makesrna/intern/rna_property.c
@@ -35,6 +35,15 @@
#include "WM_types.h"
+EnumPropertyItem gameproperty_type_items[] ={
+ {GPROP_BOOL, "BOOL", 0, "Boolean", "Boolean Property"},
+ {GPROP_INT, "INT", 0, "Integer", "Integer Property"},
+ {GPROP_FLOAT, "FLOAT", 0, "Float", "Floating-Point Property"},
+ {GPROP_STRING, "STRING", 0, "String", "String Property"},
+ {GPROP_TIME, "TIMER", 0, "Timer", "Timer Property"},
+ {0, NULL, 0, NULL, NULL}};
+
+
#ifdef RNA_RUNTIME
#include "BKE_property.h"
@@ -98,14 +107,6 @@ void RNA_def_gameproperty(BlenderRNA *brna)
StructRNA *srna;
PropertyRNA *prop;
- static EnumPropertyItem gameproperty_type_items[] ={
- {GPROP_BOOL, "BOOL", 0, "Boolean", "Boolean Property"},
- {GPROP_INT, "INT", 0, "Integer", "Integer Property"},
- {GPROP_FLOAT, "FLOAT", 0, "Float", "Floating-Point Property"},
- {GPROP_STRING, "STRING", 0, "String", "String Property"},
- {GPROP_TIME, "TIMER", 0, "Timer", "Timer Property"},
- {0, NULL, 0, NULL, NULL}};
-
/* Base Struct for GameProperty */
srna= RNA_def_struct(brna, "GameProperty", NULL);
RNA_def_struct_ui_text(srna , "Game Property", "Game engine user defined object property");
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index 72cab2ce104..0d7a7195b44 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -3883,14 +3883,14 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
RNA_def_property_float_sdna(prop, NULL, "fg_stamp");
RNA_def_property_array(prop, 4);
RNA_def_property_range(prop,0.0,1.0);
- RNA_def_property_ui_text(prop, "Stamp Text Color", "Color to use for stamp text");
+ RNA_def_property_ui_text(prop, "Text Color", "Color to use for stamp text");
RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
prop= RNA_def_property(srna, "stamp_background", PROP_FLOAT, PROP_COLOR);
RNA_def_property_float_sdna(prop, NULL, "bg_stamp");
RNA_def_property_array(prop, 4);
RNA_def_property_range(prop,0.0,1.0);
- RNA_def_property_ui_text(prop, "Stamp Background", "Color to use behind stamp text");
+ RNA_def_property_ui_text(prop, "Background", "Color to use behind stamp text");
RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL);
/* sequencer draw options */
diff --git a/source/blender/makesrna/intern/rna_screen.c b/source/blender/makesrna/intern/rna_screen.c
index c8792ef30f3..fa1f6c72430 100644
--- a/source/blender/makesrna/intern/rna_screen.c
+++ b/source/blender/makesrna/intern/rna_screen.c
@@ -54,6 +54,7 @@ EnumPropertyItem region_type_items[] = {
#ifdef RNA_RUNTIME
+#include "BKE_global.h"
static void rna_Screen_scene_set(PointerRNA *ptr, PointerRNA value)
{
@@ -62,7 +63,6 @@ static void rna_Screen_scene_set(PointerRNA *ptr, PointerRNA value)
if(value.data == NULL)
return;
- /* exception: can't set screens inside of area/region handers */
sc->newscene= value.data;
}
@@ -70,10 +70,14 @@ static void rna_Screen_scene_update(bContext *C, PointerRNA *ptr)
{
bScreen *sc= (bScreen*)ptr->data;
- /* exception: can't set screens inside of area/region handers, and must
- use context so notifier gets to the right window */
+ /* exception: must use context so notifier gets to the right window */
if(sc->newscene) {
+ ED_screen_set_scene(C, sc->newscene);
WM_event_add_notifier(C, NC_SCENE|ND_SCENEBROWSE, sc->newscene);
+
+ if(G.f & G_DEBUG)
+ printf("scene set %p\n", sc->newscene);
+
sc->newscene= NULL;
}
}
diff --git a/source/blender/makesrna/intern/rna_tracking.c b/source/blender/makesrna/intern/rna_tracking.c
index bbec6484c5f..c29d655feb2 100644
--- a/source/blender/makesrna/intern/rna_tracking.c
+++ b/source/blender/makesrna/intern/rna_tracking.c
@@ -305,7 +305,14 @@ static void rna_trackingObject_tracks_begin(CollectionPropertyIterator *iter, Po
{
MovieTrackingObject *object= (MovieTrackingObject* )ptr->data;
- rna_iterator_listbase_begin(iter, &object->tracks, NULL);
+ if(object->flag&TRACKING_OBJECT_CAMERA) {
+ MovieClip *clip= (MovieClip*)ptr->id.data;
+
+ rna_iterator_listbase_begin(iter, &clip->tracking.tracks, NULL);
+ }
+ else {
+ rna_iterator_listbase_begin(iter, &object->tracks, NULL);
+ }
}
static PointerRNA rna_tracking_active_object_get(PointerRNA *ptr)
diff --git a/source/blender/modifiers/SConscript b/source/blender/modifiers/SConscript
index ce413faec86..03fcee399bd 100644
--- a/source/blender/modifiers/SConscript
+++ b/source/blender/modifiers/SConscript
@@ -14,10 +14,10 @@ incs += ' ' + env['BF_ZLIB_INC']
defs = []
if env ['WITH_BF_BOOLEAN']:
- incs += ' #/intern/dualcon'
defs.append('WITH_MOD_BOOLEAN')
if env['WITH_BF_REMESH']:
+ incs += ' #/intern/dualcon'
defs.append('WITH_MOD_REMESH')
if env ['WITH_BF_DECIMATE']:
diff --git a/source/blender/modifiers/intern/MOD_remesh.c b/source/blender/modifiers/intern/MOD_remesh.c
index c698985efc3..bc67237fb40 100644
--- a/source/blender/modifiers/intern/MOD_remesh.c
+++ b/source/blender/modifiers/intern/MOD_remesh.c
@@ -1,27 +1,24 @@
/*
-* $Id$
-*
-* ***** 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) 2011 by Nicholas Bishop.
-*
-* ***** END GPL LICENSE BLOCK *****
-*
-*/
+ * ***** 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) 2011 by Nicholas Bishop.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
/** \file blender/modifiers/intern/MOD_remesh.c
* \ingroup modifiers
@@ -152,7 +149,7 @@ static DerivedMesh *applyModifier(ModifierData *md,
DualConInput input;
DerivedMesh *result;
DualConFlags flags = 0;
- DualConMode mode;
+ DualConMode mode = 0;
rmd = (RemeshModifierData*)md;
diff --git a/source/blender/modifiers/intern/MOD_util.c b/source/blender/modifiers/intern/MOD_util.c
index cc7a5e54fbd..5be7eb6af3d 100644
--- a/source/blender/modifiers/intern/MOD_util.c
+++ b/source/blender/modifiers/intern/MOD_util.c
@@ -107,36 +107,19 @@ void get_texture_coords(MappingInfoModifierData *dmd, Object *ob,
/* verts are given the UV from the first face that uses them */
for(i = 0, mf = mface; i < numFaces; ++i, ++mf, ++tf) {
- if(!done[mf->v1]) {
- texco[mf->v1][0] = tf->uv[0][0];
- texco[mf->v1][1] = tf->uv[0][1];
- texco[mf->v1][2] = 0;
- done[mf->v1] = 1;
- }
- if(!done[mf->v2]) {
- texco[mf->v2][0] = tf->uv[1][0];
- texco[mf->v2][1] = tf->uv[1][1];
- texco[mf->v2][2] = 0;
- done[mf->v2] = 1;
- }
- if(!done[mf->v3]) {
- texco[mf->v3][0] = tf->uv[2][0];
- texco[mf->v3][1] = tf->uv[2][1];
- texco[mf->v3][2] = 0;
- done[mf->v3] = 1;
- }
- if(!done[mf->v4]) {
- texco[mf->v4][0] = tf->uv[3][0];
- texco[mf->v4][1] = tf->uv[3][1];
- texco[mf->v4][2] = 0;
- done[mf->v4] = 1;
- }
- }
+ unsigned int fidx= mf->v4 ? 3:2;
+
+ do {
+ unsigned int vidx = *(&mf->v1 + fidx);
+
+ if (done[vidx] == 0) {
+ /* remap UVs from [0, 1] to [-1, 1] */
+ texco[vidx][0] = (tf->uv[fidx][0] * 2.0f) - 1.0f;
+ texco[vidx][1] = (tf->uv[fidx][1] * 2.0f) - 1.0f;
+ done[vidx] = 1;
+ }
- /* remap UVs from [0, 1] to [-1, 1] */
- for(i = 0; i < numVerts; ++i) {
- texco[i][0] = texco[i][0] * 2 - 1;
- texco[i][1] = texco[i][1] * 2 - 1;
+ } while (fidx--);
}
MEM_freeN(done);
diff --git a/source/blender/modifiers/intern/MOD_uvproject.c b/source/blender/modifiers/intern/MOD_uvproject.c
index 38c2073b6a5..c89fdb3a0ee 100644
--- a/source/blender/modifiers/intern/MOD_uvproject.c
+++ b/source/blender/modifiers/intern/MOD_uvproject.c
@@ -287,41 +287,34 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd,
if(override_image || !image || tface->tpage == image) {
if(num_projectors == 1) {
if(projectors[0].uci) {
- project_from_camera(tface->uv[0], coords[mf->v1], projectors[0].uci);
- project_from_camera(tface->uv[1], coords[mf->v2], projectors[0].uci);
- project_from_camera(tface->uv[2], coords[mf->v3], projectors[0].uci);
- if(mf->v4)
- project_from_camera(tface->uv[3], coords[mf->v4], projectors[0].uci);
+ unsigned int fidx= mf->v4 ? 3:2;
+ do {
+ unsigned int vidx= *(&mf->v1 + fidx);
+ project_from_camera(tface->uv[fidx], coords[vidx], projectors[0].uci);
+ } while (fidx--);
}
else {
/* apply transformed coords as UVs */
- copy_v2_v2(tface->uv[0], coords[mf->v1]);
- copy_v2_v2(tface->uv[1], coords[mf->v2]);
- copy_v2_v2(tface->uv[2], coords[mf->v3]);
- if (mf->v4) {
- copy_v2_v2(tface->uv[3], coords[mf->v4]);
- }
+ unsigned int fidx= mf->v4 ? 3:2;
+ do {
+ unsigned int vidx= *(&mf->v1 + fidx);
+ copy_v2_v2(tface->uv[fidx], coords[vidx]);
+ } while (fidx--);
}
} else {
/* multiple projectors, select the closest to face normal
* direction
*/
- float co1[3], co2[3], co3[3], co4[3];
float face_no[3];
int j;
Projector *best_projector;
float best_dot;
- copy_v3_v3(co1, coords[mf->v1]);
- copy_v3_v3(co2, coords[mf->v2]);
- copy_v3_v3(co3, coords[mf->v3]);
-
/* get the untransformed face normal */
if(mf->v4) {
- copy_v3_v3(co4, coords[mf->v4]);
- normal_quad_v3(face_no, co1, co2, co3, co4);
+ normal_quad_v3(face_no, coords[mf->v1], coords[mf->v2], coords[mf->v3], coords[mf->v4]);
} else {
- normal_tri_v3(face_no, co1, co2, co3);
+ normal_tri_v3(face_no, coords[mf->v1], coords[mf->v2], coords[mf->v3]);
}
/* find the projector which the face points at most directly
@@ -340,26 +333,23 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd,
}
if(best_projector->uci) {
- project_from_camera(tface->uv[0], coords[mf->v1], best_projector->uci);
- project_from_camera(tface->uv[1], coords[mf->v2], best_projector->uci);
- project_from_camera(tface->uv[2], coords[mf->v3], best_projector->uci);
- if(mf->v4)
- project_from_camera(tface->uv[3], coords[mf->v4], best_projector->uci);
+ unsigned int fidx= mf->v4 ? 3:2;
+ do {
+ unsigned int vidx= *(&mf->v1 + fidx);
+ project_from_camera(tface->uv[fidx], coords[vidx], best_projector->uci);
+ } while (fidx--);
}
else {
- mul_project_m4_v3(best_projector->projmat, co1);
- mul_project_m4_v3(best_projector->projmat, co2);
- mul_project_m4_v3(best_projector->projmat, co3);
- if(mf->v4)
- mul_project_m4_v3(best_projector->projmat, co4);
+ unsigned int fidx= mf->v4 ? 3:2;
+ do {
+ unsigned int vidx= *(&mf->v1 + fidx);
+ float tco[3];
- /* apply transformed coords as UVs */
- copy_v2_v2(tface->uv[0], co1);
- copy_v2_v2(tface->uv[1], co2);
- copy_v2_v2(tface->uv[2], co3);
- if (mf->v4) {
- copy_v2_v2(tface->uv[3], co4);
- }
+ copy_v3_v3(tco, coords[vidx]);
+ mul_project_m4_v3(best_projector->projmat, tco);
+ copy_v2_v2(tface->uv[fidx], tco);
+
+ } while (fidx--);
}
}
}
diff --git a/source/blender/modifiers/intern/MOD_wave.c b/source/blender/modifiers/intern/MOD_wave.c
index 398a078bf38..e83aa9e3fb9 100644
--- a/source/blender/modifiers/intern/MOD_wave.c
+++ b/source/blender/modifiers/intern/MOD_wave.c
@@ -73,7 +73,7 @@ static void initData(ModifierData *md)
wmd->lifetime= 0.0f;
wmd->damp= 10.0f;
wmd->falloff= 0.0f;
- wmd->texmapping = MOD_WAV_MAP_LOCAL;
+ wmd->texmapping = MOD_DISP_MAP_LOCAL;
wmd->defgrp_name[0] = 0;
}
@@ -160,7 +160,7 @@ static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
/* ask for UV coordinates if we need them */
- if(wmd->texture && wmd->texmapping == MOD_WAV_MAP_UV)
+ if(wmd->texture && wmd->texmapping == MOD_DISP_MAP_UV)
dataMask |= CD_MASK_MTFACE;
/* ask for vertexgroups if we need them */
@@ -170,91 +170,6 @@ static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
return dataMask;
}
-static void wavemod_get_texture_coords(WaveModifierData *wmd, Object *ob,
- DerivedMesh *dm,
- float (*co)[3], float (*texco)[3],
- int numVerts)
-{
- int i;
- int texmapping = wmd->texmapping;
-
- if(texmapping == MOD_WAV_MAP_OBJECT) {
- if(wmd->map_object)
- invert_m4_m4(wmd->map_object->imat, wmd->map_object->obmat);
- else /* if there is no map object, default to local */
- texmapping = MOD_WAV_MAP_LOCAL;
- }
-
- /* UVs need special handling, since they come from faces */
- if(texmapping == MOD_WAV_MAP_UV) {
- if(CustomData_has_layer(&dm->faceData, CD_MTFACE)) {
- MFace *mface = dm->getFaceArray(dm);
- MFace *mf;
- char *done = MEM_callocN(sizeof(*done) * numVerts,
- "get_texture_coords done");
- int numFaces = dm->getNumFaces(dm);
- char uvname[32];
- MTFace *tf;
-
- CustomData_validate_layer_name(&dm->faceData, CD_MTFACE, wmd->uvlayer_name, uvname);
- tf = CustomData_get_layer_named(&dm->faceData, CD_MTFACE, uvname);
-
- /* verts are given the UV from the first face that uses them */
- for(i = 0, mf = mface; i < numFaces; ++i, ++mf, ++tf) {
- if(!done[mf->v1]) {
- texco[mf->v1][0] = tf->uv[0][0];
- texco[mf->v1][1] = tf->uv[0][1];
- texco[mf->v1][2] = 0;
- done[mf->v1] = 1;
- }
- if(!done[mf->v2]) {
- texco[mf->v2][0] = tf->uv[1][0];
- texco[mf->v2][1] = tf->uv[1][1];
- texco[mf->v2][2] = 0;
- done[mf->v2] = 1;
- }
- if(!done[mf->v3]) {
- texco[mf->v3][0] = tf->uv[2][0];
- texco[mf->v3][1] = tf->uv[2][1];
- texco[mf->v3][2] = 0;
- done[mf->v3] = 1;
- }
- if(!done[mf->v4]) {
- texco[mf->v4][0] = tf->uv[3][0];
- texco[mf->v4][1] = tf->uv[3][1];
- texco[mf->v4][2] = 0;
- done[mf->v4] = 1;
- }
- }
-
- /* remap UVs from [0, 1] to [-1, 1] */
- for(i = 0; i < numVerts; ++i) {
- texco[i][0] = texco[i][0] * 2 - 1;
- texco[i][1] = texco[i][1] * 2 - 1;
- }
-
- MEM_freeN(done);
- return;
- } else /* if there are no UVs, default to local */
- texmapping = MOD_WAV_MAP_LOCAL;
- }
-
- for(i = 0; i < numVerts; ++i, ++co, ++texco) {
- switch(texmapping) {
- case MOD_WAV_MAP_LOCAL:
- copy_v3_v3(*texco, *co);
- break;
- case MOD_WAV_MAP_GLOBAL:
- mul_v3_m4v3(*texco, ob->obmat, *co);
- break;
- case MOD_WAV_MAP_OBJECT:
- mul_v3_m4v3(*texco, ob->obmat, *co);
- mul_m4_v3(wmd->map_object->imat, *texco);
- break;
- }
- }
-}
-
static void waveModifier_do(WaveModifierData *md,
Scene *scene, Object *ob, DerivedMesh *dm,
float (*vertexCos)[3], int numVerts)
@@ -305,7 +220,7 @@ static void waveModifier_do(WaveModifierData *md,
if(wmd->texture) {
tex_co = MEM_mallocN(sizeof(*tex_co) * numVerts,
"waveModifier_do tex_co");
- wavemod_get_texture_coords(wmd, ob, dm, vertexCos, tex_co, numVerts);
+ get_texture_coords((MappingInfoModifierData *)wmd, ob, dm, vertexCos, tex_co, numVerts);
}
if(lifefac != 0.0f) {
diff --git a/source/blender/nodes/composite/node_composite_util.c b/source/blender/nodes/composite/node_composite_util.c
index 72037f232ad..c99cae7ed7b 100644
--- a/source/blender/nodes/composite/node_composite_util.c
+++ b/source/blender/nodes/composite/node_composite_util.c
@@ -427,6 +427,18 @@ static float *compbuf_get_pixel(CompBuf *cbuf, float *defcol, float *use, int x,
/* **************************************************** */
+static CompBuf *composit_check_compbuf(CompBuf *cbuf, int type, CompBuf *outbuf)
+{
+ /* check type */
+ CompBuf *dbuf= typecheck_compbuf(cbuf, type);
+
+ /* if same as output and translated, duplicate so pixels don't interfere */
+ if(dbuf == outbuf && !dbuf->rect_procedural && (dbuf->xof || dbuf->yof))
+ dbuf= dupalloc_compbuf(dbuf);
+
+ return dbuf;
+}
+
/* Pixel-to-Pixel operation, 1 Image in, 1 out */
void composit1_pixel_processor(bNode *node, CompBuf *out, CompBuf *src_buf, float *src_col,
void (*func)(bNode *, float *, float *),
@@ -437,7 +449,7 @@ void composit1_pixel_processor(bNode *node, CompBuf *out, CompBuf *src_buf, floa
float color[4]; /* local color if compbuf is procedural */
int xrad, yrad, x, y;
- src_use= typecheck_compbuf(src_buf, src_type);
+ src_use= composit_check_compbuf(src_buf, src_type, out);
xrad= out->xrad;
yrad= out->yrad;
@@ -463,8 +475,8 @@ void composit2_pixel_processor(bNode *node, CompBuf *out, CompBuf *src_buf, floa
float color[4]; /* local color if compbuf is procedural */
int xrad, yrad, x, y;
- src_use= typecheck_compbuf(src_buf, src_type);
- fac_use= typecheck_compbuf(fac_buf, fac_type);
+ src_use= composit_check_compbuf(src_buf, src_type, out);
+ fac_use= composit_check_compbuf(fac_buf, fac_type, out);
xrad= out->xrad;
yrad= out->yrad;
@@ -493,9 +505,9 @@ void composit3_pixel_processor(bNode *node, CompBuf *out, CompBuf *src1_buf, flo
float color[4]; /* local color if compbuf is procedural */
int xrad, yrad, x, y;
- src1_use= typecheck_compbuf(src1_buf, src1_type);
- src2_use= typecheck_compbuf(src2_buf, src2_type);
- fac_use= typecheck_compbuf(fac_buf, fac_type);
+ src1_use= composit_check_compbuf(src1_buf, src1_type, out);
+ src2_use= composit_check_compbuf(src2_buf, src2_type, out);
+ fac_use= composit_check_compbuf(fac_buf, fac_type, out);
xrad= out->xrad;
yrad= out->yrad;
@@ -529,10 +541,10 @@ void composit4_pixel_processor(bNode *node, CompBuf *out, CompBuf *src1_buf, flo
float color[4]; /* local color if compbuf is procedural */
int xrad, yrad, x, y;
- src1_use= typecheck_compbuf(src1_buf, src1_type);
- src2_use= typecheck_compbuf(src2_buf, src2_type);
- fac1_use= typecheck_compbuf(fac1_buf, fac1_type);
- fac2_use= typecheck_compbuf(fac2_buf, fac2_type);
+ src1_use= composit_check_compbuf(src1_buf, src1_type, out);
+ src2_use= composit_check_compbuf(src2_buf, src2_type, out);
+ fac1_use= composit_check_compbuf(fac1_buf, fac1_type, out);
+ fac2_use= composit_check_compbuf(fac2_buf, fac2_type, out);
xrad= out->xrad;
yrad= out->yrad;
diff --git a/source/blender/nodes/intern/node_common.c b/source/blender/nodes/intern/node_common.c
index 5ad84da45d2..fdce1f92948 100644
--- a/source/blender/nodes/intern/node_common.c
+++ b/source/blender/nodes/intern/node_common.c
@@ -609,7 +609,7 @@ void node_group_expose_all_sockets(bNodeTree *ngroup)
for (node=ngroup->nodes.first; node; node=node->next) {
for (sock=node->inputs.first; sock; sock=sock->next) {
- if (!sock->link && !(sock->flag & SOCK_HIDDEN)) {
+ if (!sock->link && !nodeSocketIsHidden(sock)) {
gsock = node_group_add_socket(ngroup, sock->name, sock->type, SOCK_IN);
/* initialize the default value. */
@@ -619,7 +619,7 @@ void node_group_expose_all_sockets(bNodeTree *ngroup)
}
}
for (sock=node->outputs.first; sock; sock=sock->next) {
- if (nodeCountSocketLinks(ngroup, sock)==0 && !(sock->flag & SOCK_HIDDEN)) {
+ if (nodeCountSocketLinks(ngroup, sock)==0 && !nodeSocketIsHidden(sock)) {
gsock = node_group_add_socket(ngroup, sock->name, sock->type, SOCK_OUT);
/* initialize the default value. */
diff --git a/source/blender/nodes/shader/node_shader_util.c b/source/blender/nodes/shader/node_shader_util.c
index 8b8afc3d846..1bfb986fdde 100644
--- a/source/blender/nodes/shader/node_shader_util.c
+++ b/source/blender/nodes/shader/node_shader_util.c
@@ -184,7 +184,7 @@ void nodeShaderSynchronizeID(bNode *node, int copyto)
/* hrmf, case in loop isnt super fast, but we dont edit 100s of material at same time either! */
for(a=0, sock= node->inputs.first; sock; sock= sock->next, a++) {
- if(!(sock->flag & SOCK_HIDDEN)) {
+ if(!nodeSocketIsHidden(sock)) {
if(copyto) {
switch(a) {
case MAT_IN_COLOR:
diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c
index d911fcb99b1..9dfbe64e905 100644
--- a/source/blender/python/intern/bpy_rna.c
+++ b/source/blender/python/intern/bpy_rna.c
@@ -4073,7 +4073,6 @@ static PyObject *pyrna_struct_as_pointer(BPy_StructRNA *self)
return PyLong_FromVoidPtr(self->ptr.data);
}
-/* TODO, get (string, lib) pair */
PyDoc_STRVAR(pyrna_prop_collection_get_doc,
".. method:: get(key, default=None)\n"
"\n"
@@ -4120,6 +4119,51 @@ static PyObject *pyrna_prop_collection_get(BPy_PropertyRNA *self, PyObject *args
return Py_INCREF(def), def;
}
+PyDoc_STRVAR(pyrna_prop_collection_find_doc,
+".. method:: find(key)\n"
+"\n"
+" Returns the index of a key in a collection or -1 when not found\n"
+" (matches pythons string find function of the same name).\n"
+"\n"
+" :arg key: The identifier for the collection member.\n"
+" :type key: string\n"
+" :return: index of the key.\n"
+" :rtype: int\n"
+);
+static PyObject *pyrna_prop_collection_find(BPy_PropertyRNA *self, PyObject *key_ob)
+{
+ Py_ssize_t key_len_ssize_t;
+ const char *key = _PyUnicode_AsStringAndSize(key_ob, &key_len_ssize_t);
+ const int key_len = (int)key_len_ssize_t; /* comare with same type */
+
+ char name[256], *nameptr;
+ int namelen;
+ int i = 0;
+ int index = -1;
+
+ PYRNA_PROP_CHECK_OBJ(self);
+
+ RNA_PROP_BEGIN(&self->ptr, itemptr, self->prop) {
+ nameptr = RNA_struct_name_get_alloc(&itemptr, name, sizeof(name), &namelen);
+
+ if (nameptr) {
+ if ((key_len == namelen) && memcmp(nameptr, key, key_len) == 0) {
+ index = i;
+ break;
+ }
+
+ if (name != nameptr) {
+ MEM_freeN(nameptr);
+ }
+ }
+
+ i++;
+ }
+ RNA_PROP_END;
+
+ return PyLong_FromSsize_t(index);
+}
+
static void foreach_attr_type( BPy_PropertyRNA *self, const char *attr,
/* values to assign */
RawPropertyType *raw_type, int *attr_tot, int *attr_signed)
@@ -4503,6 +4547,7 @@ static struct PyMethodDef pyrna_prop_collection_methods[] = {
{"values", (PyCFunction)pyrna_prop_collection_values, METH_NOARGS, pyrna_prop_collection_values_doc},
{"get", (PyCFunction)pyrna_prop_collection_get, METH_VARARGS, pyrna_prop_collection_get_doc},
+ {"find", (PyCFunction)pyrna_prop_collection_find, METH_O, pyrna_prop_collection_find_doc},
{NULL, NULL, 0, NULL}
};
diff --git a/source/blender/python/mathutils/mathutils_Matrix.c b/source/blender/python/mathutils/mathutils_Matrix.c
index 0e52d43b525..f10d8c48c92 100644
--- a/source/blender/python/mathutils/mathutils_Matrix.c
+++ b/source/blender/python/mathutils/mathutils_Matrix.c
@@ -2409,13 +2409,13 @@ static int MatrixAccess_traverse(MatrixAccessObject *self, visitproc visit, void
return 0;
}
-int MatrixAccess_clear(MatrixAccessObject *self)
+static int MatrixAccess_clear(MatrixAccessObject *self)
{
Py_CLEAR(self->matrix_user);
return 0;
}
-void MatrixAccess_dealloc(MatrixAccessObject *self)
+static void MatrixAccess_dealloc(MatrixAccessObject *self)
{
if (self->matrix_user) {
PyObject_GC_UnTrack(self);
@@ -2434,6 +2434,38 @@ static int MatrixAccess_len(MatrixAccessObject *self)
self->matrix_user->num_col;
}
+static PyObject *MatrixAccess_slice(MatrixAccessObject *self, int begin, int end)
+{
+ PyObject *tuple;
+ int count;
+
+ /* row/col access */
+ MatrixObject *matrix_user = self->matrix_user;
+ int matrix_access_len;
+ PyObject *(*Matrix_item_new)(MatrixObject *, int);
+
+ if (self->type == MAT_ACCESS_ROW) {
+ matrix_access_len = matrix_user->num_row;
+ Matrix_item_new = Matrix_item_row;
+ }
+ else { /* MAT_ACCESS_ROW */
+ matrix_access_len = matrix_user->num_col;
+ Matrix_item_new = Matrix_item_col;
+ }
+
+ CLAMP(begin, 0, matrix_access_len);
+ if (end < 0) end = (matrix_access_len + 1) + end;
+ CLAMP(end, 0, matrix_access_len);
+ begin = MIN2(begin, end);
+
+ tuple = PyTuple_New(end - begin);
+ for (count = begin; count < end; count++) {
+ PyTuple_SET_ITEM(tuple, count - begin, Matrix_item_new(matrix_user, count));
+ }
+
+ return tuple;
+}
+
static PyObject *MatrixAccess_subscript(MatrixAccessObject *self, PyObject *item)
{
MatrixObject *matrix_user = self->matrix_user;
@@ -2454,7 +2486,24 @@ static PyObject *MatrixAccess_subscript(MatrixAccessObject *self, PyObject *item
return Matrix_item_col(matrix_user, i);
}
}
- /* TODO, slice */
+ else if (PySlice_Check(item)) {
+ Py_ssize_t start, stop, step, slicelength;
+
+ if (PySlice_GetIndicesEx((void *)item, MatrixAccess_len(self), &start, &stop, &step, &slicelength) < 0)
+ return NULL;
+
+ if (slicelength <= 0) {
+ return PyTuple_New(0);
+ }
+ else if (step == 1) {
+ return MatrixAccess_slice(self, start, stop);
+ }
+ else {
+ PyErr_SetString(PyExc_IndexError,
+ "slice steps not supported with matrix accessors");
+ return NULL;
+ }
+ }
else {
PyErr_Format(PyExc_TypeError,
"matrix indices must be integers, not %.200s",
@@ -2493,6 +2542,22 @@ static int MatrixAccess_ass_subscript(MatrixAccessObject *self, PyObject *item,
}
}
+static PyObject *MatrixAccess_iter(MatrixAccessObject *self)
+{
+ /* Try get values from a collection */
+ PyObject *ret;
+ PyObject *iter = NULL;
+ ret = MatrixAccess_slice(self, 0, MATRIX_MAX_DIM);
+
+ /* we know this is a tuple so no need to PyIter_Check
+ * otherwise it could be NULL (unlikely) if conversion failed */
+ if (ret) {
+ iter = PyObject_GetIter(ret);
+ Py_DECREF(ret);
+ }
+
+ return iter;
+}
static PyMappingMethods MatrixAccess_AsMapping = {
(lenfunc)MatrixAccess_len,
@@ -2525,6 +2590,8 @@ PyTypeObject matrix_access_Type = {
(traverseproc)MatrixAccess_traverse, //tp_traverse
(inquiry)MatrixAccess_clear, //tp_clear
NULL /* (richcmpfunc)MatrixAccess_richcmpr */ /* TODO*/, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ (getiterfunc)MatrixAccess_iter, /* getiterfunc tp_iter; */
};
static PyObject *MatrixAccess_CreatePyObject(MatrixObject *matrix, const eMatrixAccess_t type)
diff --git a/source/blender/python/mathutils/mathutils_Vector.c b/source/blender/python/mathutils/mathutils_Vector.c
index e137c7846bb..5848e6e8c75 100644
--- a/source/blender/python/mathutils/mathutils_Vector.c
+++ b/source/blender/python/mathutils/mathutils_Vector.c
@@ -334,18 +334,18 @@ PyDoc_STRVAR(Vector_normalize_doc,
"\n"
" Normalize the vector, making the length of the vector always 1.0.\n"
"\n"
-" .. warning:: Normalizing a vector where all values are zero results\n"
-" in all axis having a nan value (not a number).\n"
+" .. warning:: Normalizing a vector where all values are zero has no effect.\n"
"\n"
" .. note:: Normalize works for vectors of all sizes,\n"
" however 4D Vectors w axis is left untouched.\n"
);
static PyObject *Vector_normalize(VectorObject *self)
{
+ int size = (self->size == 4 ? 3 : self->size);
if (BaseMath_ReadCallback(self) == -1)
return NULL;
- normalize_vn(self->vec, self->size);
+ normalize_vn(self->vec, size);
(void)BaseMath_WriteCallback(self);
Py_RETURN_NONE;
@@ -1480,10 +1480,10 @@ static PyObject *Vector_isub(PyObject *v1, PyObject *v2)
mulplication*/
-/* COLUMN VECTOR Multiplication (Vector X Matrix)
- * [a] * [1][4][7]
- * [b] * [2][5][8]
- * [c] * [3][6][9]
+/* COLUMN VECTOR Multiplication (Matrix X Vector)
+ * [1][4][7] [a]
+ * [2][5][8] * [b]
+ * [3][6][9] [c]
*
* note: vector/matrix multiplication IS NOT COMMUTATIVE!!!!
* note: assume read callbacks have been done first.
@@ -1500,8 +1500,8 @@ int column_vector_multiplication(float r_vec[MAX_DIMENSIONS], VectorObject *vec,
else {
PyErr_SetString(PyExc_TypeError,
"matrix * vector: "
- "matrix.row_size and len(vector) must be the same, "
- "except for 3D vector * 4x4 matrix.");
+ "len(matrix.col) and len(vector) must be the same, "
+ "except for 4x4 matrix * 3D vector.");
return -1;
}
}
diff --git a/source/blender/render/CMakeLists.txt b/source/blender/render/CMakeLists.txt
index 9982eb86460..4ca8f6213bb 100644
--- a/source/blender/render/CMakeLists.txt
+++ b/source/blender/render/CMakeLists.txt
@@ -67,6 +67,7 @@ set(SRC
intern/source/pointdensity.c
intern/source/rayshade.c
intern/source/rendercore.c
+ intern/source/render_result.c
intern/source/render_texture.c
intern/source/renderdatabase.c
intern/source/shadbuf.c
@@ -97,6 +98,7 @@ set(SRC
intern/include/rayintersection.h
intern/include/raycounter.h
intern/include/render_types.h
+ intern/include/render_result.h
intern/include/rendercore.h
intern/include/renderdatabase.h
intern/include/renderpipeline.h
diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h
index ba211ba396d..1016a242341 100644
--- a/source/blender/render/extern/include/RE_pipeline.h
+++ b/source/blender/render/extern/include/RE_pipeline.h
@@ -182,9 +182,6 @@ float *RE_RenderLayerGetPass(struct RenderLayer *rl, int passtype);
/* obligatory initialize call, disprect is optional */
void RE_InitState (struct Render *re, struct Render *source, struct RenderData *rd, struct SceneRenderLayer *srl, int winx, int winy, rcti *disprect);
-/* use this to change disprect of active render */
-void RE_SetDispRect (struct Render *re, rcti *disprect);
-
/* set up the viewplane/perspective matrix, three choices */
struct Object *RE_GetCamera(struct Render *re); /* return camera override if set */
void RE_SetCamera(struct Render *re, struct Object *camera);
diff --git a/source/blender/render/intern/include/render_result.h b/source/blender/render/intern/include/render_result.h
new file mode 100644
index 00000000000..93cbc6fe9c9
--- /dev/null
+++ b/source/blender/render/intern/include/render_result.h
@@ -0,0 +1,94 @@
+/*
+ * ***** 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) 2007 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/render/intern/include/render_result.h
+ * \ingroup render
+ */
+
+#ifndef RENDER_RESULT_H
+#define RENDER_RESULT_H
+
+#define PASS_VECTOR_MAX 10000.0f
+
+#define RR_USE_MEM 0
+#define RR_USE_EXR 1
+
+struct ImBuf;
+struct ListBase;
+struct Render;
+struct RenderData;
+struct RenderLayer;
+struct RenderResult;
+struct Scene;
+struct rcti;
+
+/* New */
+
+struct RenderResult *render_result_new(struct Render *re,
+ struct rcti *partrct, int crop, int savebuffers);
+struct RenderResult *render_result_new_full_sample(struct Render *re,
+ struct ListBase *lb, struct rcti *partrct, int crop, int savebuffers);
+
+struct RenderResult *render_result_new_from_exr(void *exrhandle, int rectx, int recty);
+
+/* Merge */
+
+void render_result_merge(struct RenderResult *rr, struct RenderResult *rrpart);
+
+/* Free */
+
+void render_result_free(struct RenderResult *rr);
+void render_result_free_list(struct ListBase *lb, struct RenderResult *rr);
+
+/* Single Layer Render */
+
+void render_result_single_layer_begin(struct Render *re);
+void render_result_single_layer_end(struct Render *re);
+
+/* EXR Tile File Render */
+
+void render_result_exr_file_begin(struct Render *re);
+void render_result_exr_file_end(struct Render *re);
+
+void render_result_exr_file_merge(struct RenderResult *rr, struct RenderResult *rrpart);
+
+void render_result_exr_file_path(struct Scene *scene, int sample, char *filepath);
+int render_result_exr_file_read(struct Render *re, int sample);
+int render_result_exr_file_read_path(struct RenderResult *rr, const char *filepath);
+
+/* Combined Pixel Rect */
+
+struct ImBuf *render_result_rect_to_ibuf(struct RenderResult *rr, struct RenderData *rd);
+void render_result_rect_from_ibuf(struct RenderResult *rr, struct RenderData *rd,
+ struct ImBuf *ibuf);
+
+void render_result_rect_fill_zero(struct RenderResult *rr);
+void render_result_rect_get_pixels(struct RenderResult *rr, struct RenderData *rd,
+ unsigned int *rect, int rectx, int recty);
+
+#endif /* RENDER_RESULT_H */
+
diff --git a/source/blender/render/intern/include/renderpipeline.h b/source/blender/render/intern/include/renderpipeline.h
index fc46ea83309..9a87cf84012 100644
--- a/source/blender/render/intern/include/renderpipeline.h
+++ b/source/blender/render/intern/include/renderpipeline.h
@@ -33,22 +33,12 @@
#ifndef PIPELINE_H
#define PIPELINE_H
-struct ListBase;
struct Render;
-struct RenderResult;
struct RenderLayer;
-struct rcti;
+struct RenderResult;
struct RenderLayer *render_get_active_layer(struct Render *re, struct RenderResult *rr);
float panorama_pixel_rot(struct Render *re);
-#define PASS_VECTOR_MAX 10000.0f
-
-#define RR_USEMEM 0
-
-struct RenderResult *new_render_result(struct Render *re, struct rcti *partrct, int crop, int savebuffers);
-void merge_render_result(struct RenderResult *rr, struct RenderResult *rrpart);
-void free_render_result(struct ListBase *lb, struct RenderResult *rr);
-
#endif /* PIPELINE_H */
diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c
index dc2de5fb450..703ca23c15b 100644
--- a/source/blender/render/intern/source/external_engine.c
+++ b/source/blender/render/intern/source/external_engine.c
@@ -54,7 +54,7 @@
#include "RE_pipeline.h"
#include "render_types.h"
-#include "renderpipeline.h"
+#include "render_result.h"
/* Render Engine Types */
@@ -168,8 +168,13 @@ RenderResult *RE_engine_begin_result(RenderEngine *engine, int x, int y, int w,
disprect.ymin= y;
disprect.ymax= y+h;
- result= new_render_result(re, &disprect, 0, RR_USEMEM);
+ result= render_result_new(re, &disprect, 0, RR_USE_MEM);
BLI_addtail(&engine->fullresult, result);
+
+ result->tilerect.xmin += re->disprect.xmin;
+ result->tilerect.xmax += re->disprect.xmin;
+ result->tilerect.ymin += re->disprect.ymin;
+ result->tilerect.ymax += re->disprect.ymin;
return result;
}
@@ -190,15 +195,10 @@ void RE_engine_end_result(RenderEngine *engine, RenderResult *result)
if(!result)
return;
-
- result->tilerect.xmin += re->disprect.xmin;
- result->tilerect.xmax += re->disprect.xmin;
- result->tilerect.ymin += re->disprect.ymin;
- result->tilerect.ymax += re->disprect.ymin;
/* merge. on break, don't merge in result for preview renders, looks nicer */
if(!(re->test_break(re->tbh) && (re->r.scemode & R_PREVIEWBUTS)))
- merge_render_result(re->result, result);
+ render_result_merge(re->result, result);
/* draw */
if(!re->test_break(re->tbh)) {
@@ -207,7 +207,7 @@ void RE_engine_end_result(RenderEngine *engine, RenderResult *result)
}
/* free */
- free_render_result(&engine->fullresult, result);
+ render_result_free_list(&engine->fullresult, result);
}
/* Cancel */
@@ -286,8 +286,9 @@ int RE_engine_render(Render *re, int do_all)
/* create render result */
BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
if(re->result==NULL || !(re->r.scemode & R_PREVIEWBUTS)) {
- RE_FreeRenderResult(re->result);
- re->result= new_render_result(re, &re->disprect, 0, 0);
+ if(re->result)
+ render_result_free(re->result);
+ re->result= render_result_new(re, &re->disprect, 0, 0);
}
BLI_rw_mutex_unlock(&re->resultmutex);
@@ -316,7 +317,7 @@ int RE_engine_render(Render *re, int do_all)
if(type->render)
type->render(engine, re->scene);
- free_render_result(&engine->fullresult, engine->fullresult.first);
+ render_result_free_list(&engine->fullresult, engine->fullresult.first);
RE_engine_free(engine);
diff --git a/source/blender/render/intern/source/imagetexture.c b/source/blender/render/intern/source/imagetexture.c
index 785d9ac69d8..0b6e1b8ee01 100644
--- a/source/blender/render/intern/source/imagetexture.c
+++ b/source/blender/render/intern/source/imagetexture.c
@@ -203,6 +203,13 @@ int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], TexResul
ibuf->rect+= (ibuf->x*ibuf->y);
}
+ /* keep this before interpolation [#29761] */
+ if (tex->imaflag & TEX_USEALPHA) {
+ if ((tex->imaflag & TEX_CALCALPHA) == 0) {
+ texres->talpha = TRUE;
+ }
+ }
+
/* interpolate */
if (tex->imaflag & TEX_INTERPOL) {
float filterx, filtery;
@@ -225,11 +232,6 @@ int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], TexResul
ibuf->rect-= (ibuf->x*ibuf->y);
}
- if(tex->imaflag & TEX_USEALPHA) {
- if(tex->imaflag & TEX_CALCALPHA);
- else texres->talpha= 1;
- }
-
if(texres->nor) {
if(tex->imaflag & TEX_NORMALMAP) {
// qdn: normal from color
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index f80bea97c9b..edf8e9aeebf 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -54,7 +54,6 @@
#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_node.h"
-#include "BKE_object.h"
#include "BKE_pointcache.h"
#include "BKE_report.h"
#include "BKE_scene.h"
@@ -63,30 +62,28 @@
#include "BKE_writeavi.h" /* <------ should be replaced once with generic movie module */
#include "BLI_math.h"
-#include "BLI_blenlib.h"
+#include "BLI_listbase.h"
+#include "BLI_string.h"
+#include "BLI_path_util.h"
+#include "BLI_fileops.h"
#include "BLI_rand.h"
-#include "BLI_threads.h"
#include "BLI_callbacks.h"
-#include "BLI_utildefines.h"
#include "PIL_time.h"
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
-#include "intern/openexr/openexr_multi.h"
-
#include "RE_engine.h"
#include "RE_pipeline.h"
#include "FRS_freestyle.h"
-#include "FRS_freestyle_config.h"
/* internal */
+#include "render_result.h"
#include "render_types.h"
#include "renderpipeline.h"
#include "renderdatabase.h"
#include "rendercore.h"
-#include "envmap.h"
#include "initrender.h"
#include "shadbuf.h"
#include "pixelblending.h"
@@ -188,345 +185,7 @@ static void stats_background(void *UNUSED(arg), RenderStats *rs)
void RE_FreeRenderResult(RenderResult *res)
{
- if(res==NULL) return;
-
- while(res->layers.first) {
- RenderLayer *rl= res->layers.first;
-
- if(rl->rectf) MEM_freeN(rl->rectf);
- /* acolrect and scolrect are optionally allocated in shade_tile, only free here since it can be used for drawing */
- if(rl->acolrect) MEM_freeN(rl->acolrect);
- if(rl->scolrect) MEM_freeN(rl->scolrect);
-
- while(rl->passes.first) {
- RenderPass *rpass= rl->passes.first;
- if(rpass->rect) MEM_freeN(rpass->rect);
- BLI_remlink(&rl->passes, rpass);
- MEM_freeN(rpass);
- }
- BLI_remlink(&res->layers, rl);
- MEM_freeN(rl);
- }
-
- if(res->rect32)
- MEM_freeN(res->rect32);
- if(res->rectz)
- MEM_freeN(res->rectz);
- if(res->rectf)
- MEM_freeN(res->rectf);
- if(res->text)
- MEM_freeN(res->text);
-
- MEM_freeN(res);
-}
-
-/* version that's compatible with fullsample buffers */
-void free_render_result(ListBase *lb, RenderResult *rr)
-{
- RenderResult *rrnext;
-
- for(; rr; rr= rrnext) {
- rrnext= rr->next;
-
- if(lb && lb->first)
- BLI_remlink(lb, rr);
-
- RE_FreeRenderResult(rr);
- }
-}
-
-
-/* all layers except the active one get temporally pushed away */
-static void push_render_result(Render *re)
-{
- BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
-
- /* officially pushed result should be NULL... error can happen with do_seq */
- RE_FreeRenderResult(re->pushedresult);
-
- re->pushedresult= re->result;
- re->result= NULL;
-
- BLI_rw_mutex_unlock(&re->resultmutex);
-}
-
-/* if scemode is R_SINGLE_LAYER, at end of rendering, merge the both render results */
-static void pop_render_result(Render *re)
-{
- if(re->result==NULL) {
- printf("pop render result error; no current result!\n");
- return;
- }
-
- if(re->pushedresult) {
- BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
-
- if(re->pushedresult->rectx==re->result->rectx && re->pushedresult->recty==re->result->recty) {
- /* find which layer in pushedresult should be replaced */
- SceneRenderLayer *srl;
- RenderLayer *rlpush;
- RenderLayer *rl= re->result->layers.first;
- int nr;
-
- /* render result should be empty after this */
- BLI_remlink(&re->result->layers, rl);
-
- /* reconstruct render result layers */
- for(nr=0, srl= re->scene->r.layers.first; srl; srl= srl->next, nr++) {
- if(nr==re->r.actlay)
- BLI_addtail(&re->result->layers, rl);
- else {
- rlpush= RE_GetRenderLayer(re->pushedresult, srl->name);
- if(rlpush) {
- BLI_remlink(&re->pushedresult->layers, rlpush);
- BLI_addtail(&re->result->layers, rlpush);
- }
- }
- }
- }
-
- RE_FreeRenderResult(re->pushedresult);
- re->pushedresult= NULL;
-
- BLI_rw_mutex_unlock(&re->resultmutex);
- }
-}
-
-/* NOTE: OpenEXR only supports 32 chars for layer+pass names
- In blender we now use max 10 chars for pass, max 20 for layer */
-static const char *get_pass_name(int passtype, int channel)
-{
-
- if(passtype == SCE_PASS_COMBINED) {
- if(channel==-1) return "Combined";
- if(channel==0) return "Combined.R";
- if(channel==1) return "Combined.G";
- if(channel==2) return "Combined.B";
- return "Combined.A";
- }
- if(passtype == SCE_PASS_Z) {
- if(channel==-1) return "Depth";
- return "Depth.Z";
- }
- if(passtype == SCE_PASS_VECTOR) {
- if(channel==-1) return "Vector";
- if(channel==0) return "Vector.X";
- if(channel==1) return "Vector.Y";
- if(channel==2) return "Vector.Z";
- return "Vector.W";
- }
- if(passtype == SCE_PASS_NORMAL) {
- if(channel==-1) return "Normal";
- if(channel==0) return "Normal.X";
- if(channel==1) return "Normal.Y";
- return "Normal.Z";
- }
- if(passtype == SCE_PASS_UV) {
- if(channel==-1) return "UV";
- if(channel==0) return "UV.U";
- if(channel==1) return "UV.V";
- return "UV.A";
- }
- if(passtype == SCE_PASS_RGBA) {
- if(channel==-1) return "Color";
- if(channel==0) return "Color.R";
- if(channel==1) return "Color.G";
- if(channel==2) return "Color.B";
- return "Color.A";
- }
- if(passtype == SCE_PASS_EMIT) {
- if(channel==-1) return "Emit";
- if(channel==0) return "Emit.R";
- if(channel==1) return "Emit.G";
- return "Emit.B";
- }
- if(passtype == SCE_PASS_DIFFUSE) {
- if(channel==-1) return "Diffuse";
- if(channel==0) return "Diffuse.R";
- if(channel==1) return "Diffuse.G";
- return "Diffuse.B";
- }
- if(passtype == SCE_PASS_SPEC) {
- if(channel==-1) return "Spec";
- if(channel==0) return "Spec.R";
- if(channel==1) return "Spec.G";
- return "Spec.B";
- }
- if(passtype == SCE_PASS_SHADOW) {
- if(channel==-1) return "Shadow";
- if(channel==0) return "Shadow.R";
- if(channel==1) return "Shadow.G";
- return "Shadow.B";
- }
- if(passtype == SCE_PASS_AO) {
- if(channel==-1) return "AO";
- if(channel==0) return "AO.R";
- if(channel==1) return "AO.G";
- return "AO.B";
- }
- if(passtype == SCE_PASS_ENVIRONMENT) {
- if(channel==-1) return "Env";
- if(channel==0) return "Env.R";
- if(channel==1) return "Env.G";
- return "Env.B";
- }
- if(passtype == SCE_PASS_INDIRECT) {
- if(channel==-1) return "Indirect";
- if(channel==0) return "Indirect.R";
- if(channel==1) return "Indirect.G";
- return "Indirect.B";
- }
- if(passtype == SCE_PASS_REFLECT) {
- if(channel==-1) return "Reflect";
- if(channel==0) return "Reflect.R";
- if(channel==1) return "Reflect.G";
- return "Reflect.B";
- }
- if(passtype == SCE_PASS_REFRACT) {
- if(channel==-1) return "Refract";
- if(channel==0) return "Refract.R";
- if(channel==1) return "Refract.G";
- return "Refract.B";
- }
- if(passtype == SCE_PASS_INDEXOB) {
- if(channel==-1) return "IndexOB";
- return "IndexOB.X";
- }
- if(passtype == SCE_PASS_INDEXMA) {
- if(channel==-1) return "IndexMA";
- return "IndexMA.X";
- }
- if(passtype == SCE_PASS_MIST) {
- if(channel==-1) return "Mist";
- return "Mist.Z";
- }
- if(passtype == SCE_PASS_RAYHITS)
- {
- if(channel==-1) return "Rayhits";
- if(channel==0) return "Rayhits.R";
- if(channel==1) return "Rayhits.G";
- return "Rayhits.B";
- }
- return "Unknown";
-}
-
-static int passtype_from_name(const char *str)
-{
-
- if(strcmp(str, "Combined")==0)
- return SCE_PASS_COMBINED;
-
- if(strcmp(str, "Depth")==0)
- return SCE_PASS_Z;
-
- if(strcmp(str, "Vector")==0)
- return SCE_PASS_VECTOR;
-
- if(strcmp(str, "Normal")==0)
- return SCE_PASS_NORMAL;
-
- if(strcmp(str, "UV")==0)
- return SCE_PASS_UV;
-
- if(strcmp(str, "Color")==0)
- return SCE_PASS_RGBA;
-
- if(strcmp(str, "Emit")==0)
- return SCE_PASS_EMIT;
-
- if(strcmp(str, "Diffuse")==0)
- return SCE_PASS_DIFFUSE;
-
- if(strcmp(str, "Spec")==0)
- return SCE_PASS_SPEC;
-
- if(strcmp(str, "Shadow")==0)
- return SCE_PASS_SHADOW;
-
- if(strcmp(str, "AO")==0)
- return SCE_PASS_AO;
-
- if(strcmp(str, "Env")==0)
- return SCE_PASS_ENVIRONMENT;
-
- if(strcmp(str, "Indirect")==0)
- return SCE_PASS_INDIRECT;
-
- if(strcmp(str, "Reflect")==0)
- return SCE_PASS_REFLECT;
-
- if(strcmp(str, "Refract")==0)
- return SCE_PASS_REFRACT;
-
- if(strcmp(str, "IndexOB")==0)
- return SCE_PASS_INDEXOB;
-
- if(strcmp(str, "IndexMA")==0)
- return SCE_PASS_INDEXMA;
-
- if(strcmp(str, "Mist")==0)
- return SCE_PASS_MIST;
-
- if(strcmp(str, "RayHits")==0)
- return SCE_PASS_RAYHITS;
- return 0;
-}
-
-static void scene_unique_exr_name(Scene *scene, char *str, int sample)
-{
- char di[FILE_MAX], name[FILE_MAXFILE+MAX_ID_NAME+100], fi[FILE_MAXFILE];
-
- BLI_strncpy(di, G.main->name, FILE_MAX);
- BLI_splitdirstring(di, fi);
-
- if(sample==0)
- BLI_snprintf(name, sizeof(name), "%s_%s.exr", fi, scene->id.name+2);
- else
- BLI_snprintf(name, sizeof(name), "%s_%s%d.exr", fi, scene->id.name+2, sample);
-
- BLI_make_file_string("/", str, BLI_temporary_dir(), name);
-}
-
-static void render_unique_exr_name(Render *re, char *str, int sample)
-{
- scene_unique_exr_name(re->scene, str, sample);
-}
-
-static void render_layer_add_pass(RenderResult *rr, RenderLayer *rl, int channels, int passtype)
-{
- const char *typestr= get_pass_name(passtype, 0);
- RenderPass *rpass= MEM_callocN(sizeof(RenderPass), typestr);
- int rectsize= rr->rectx*rr->recty*channels;
-
- BLI_addtail(&rl->passes, rpass);
- rpass->passtype= passtype;
- rpass->channels= channels;
- rpass->rectx= rl->rectx;
- rpass->recty= rl->recty;
-
- if(rr->exrhandle) {
- int a;
- for(a=0; a<channels; a++)
- IMB_exr_add_channel(rr->exrhandle, rl->name, get_pass_name(passtype, a), 0, 0, NULL);
- }
- else {
- float *rect;
- int x;
-
- rpass->rect= MEM_mapallocN(sizeof(float)*rectsize, typestr);
-
- if(passtype==SCE_PASS_VECTOR) {
- /* initialize to max speed */
- rect= rpass->rect;
- for(x= rectsize-1; x>=0; x--)
- rect[x]= PASS_VECTOR_MAX;
- }
- else if(passtype==SCE_PASS_Z) {
- rect= rpass->rect;
- for(x= rectsize-1; x>=0; x--)
- rect[x]= 10e10;
- }
- }
+ render_result_free(res);
}
float *RE_RenderLayerGetPass(RenderLayer *rl, int passtype)
@@ -551,141 +210,19 @@ RenderLayer *RE_GetRenderLayer(RenderResult *rr, const char *name)
return NULL;
}
-/* called by main render as well for parts */
-/* will read info from Render *re to define layers */
-/* called in threads */
-/* re->winx,winy is coordinate space of entire image, partrct the part within */
-RenderResult *new_render_result(Render *re, rcti *partrct, int crop, int savebuffers)
+RenderResult *RE_MultilayerConvert(void *exrhandle, int rectx, int recty)
{
- RenderResult *rr;
- RenderLayer *rl;
- SceneRenderLayer *srl;
- int rectx, recty, nr;
-
- rectx= partrct->xmax - partrct->xmin;
- recty= partrct->ymax - partrct->ymin;
-
- if(rectx<=0 || recty<=0)
- return NULL;
-
- rr= MEM_callocN(sizeof(RenderResult), "new render result");
- rr->rectx= rectx;
- rr->recty= recty;
- rr->renrect.xmin= 0; rr->renrect.xmax= rectx-2*crop;
- /* crop is one or two extra pixels rendered for filtering, is used for merging and display too */
- rr->crop= crop;
-
- /* tilerect is relative coordinates within render disprect. do not subtract crop yet */
- rr->tilerect.xmin= partrct->xmin - re->disprect.xmin;
- rr->tilerect.xmax= partrct->xmax - re->disprect.xmax;
- rr->tilerect.ymin= partrct->ymin - re->disprect.ymin;
- rr->tilerect.ymax= partrct->ymax - re->disprect.ymax;
-
- if(savebuffers) {
- rr->exrhandle= IMB_exr_get_handle();
- }
-
- /* check renderdata for amount of layers */
- for(nr=0, srl= re->r.layers.first; srl; srl= srl->next, nr++) {
-
- if((re->r.scemode & R_SINGLE_LAYER) && nr!=re->r.actlay)
- continue;
- if(srl->layflag & SCE_LAY_DISABLE)
- continue;
-
- rl= MEM_callocN(sizeof(RenderLayer), "new render layer");
- BLI_addtail(&rr->layers, rl);
-
- BLI_strncpy(rl->name, srl->name, sizeof(rl->name));
- rl->lay= srl->lay;
- rl->lay_zmask= srl->lay_zmask;
- rl->layflag= srl->layflag;
- rl->passflag= srl->passflag; // for debugging: srl->passflag|SCE_PASS_RAYHITS;
- rl->pass_xor= srl->pass_xor;
- rl->light_override= srl->light_override;
- rl->mat_override= srl->mat_override;
- rl->rectx= rectx;
- rl->recty= recty;
-
- if(rr->exrhandle) {
- IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.R", 0, 0, NULL);
- IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.G", 0, 0, NULL);
- IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.B", 0, 0, NULL);
- IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.A", 0, 0, NULL);
- }
- else
- rl->rectf= MEM_mapallocN(rectx*recty*sizeof(float)*4, "Combined rgba");
-
- if(srl->passflag & SCE_PASS_Z)
- render_layer_add_pass(rr, rl, 1, SCE_PASS_Z);
- if(srl->passflag & SCE_PASS_VECTOR)
- render_layer_add_pass(rr, rl, 4, SCE_PASS_VECTOR);
- if(srl->passflag & SCE_PASS_NORMAL)
- render_layer_add_pass(rr, rl, 3, SCE_PASS_NORMAL);
- if(srl->passflag & SCE_PASS_UV)
- render_layer_add_pass(rr, rl, 3, SCE_PASS_UV);
- if(srl->passflag & SCE_PASS_RGBA)
- render_layer_add_pass(rr, rl, 4, SCE_PASS_RGBA);
- if(srl->passflag & SCE_PASS_EMIT)
- render_layer_add_pass(rr, rl, 3, SCE_PASS_EMIT);
- if(srl->passflag & SCE_PASS_DIFFUSE)
- render_layer_add_pass(rr, rl, 3, SCE_PASS_DIFFUSE);
- if(srl->passflag & SCE_PASS_SPEC)
- render_layer_add_pass(rr, rl, 3, SCE_PASS_SPEC);
- if(srl->passflag & SCE_PASS_AO)
- render_layer_add_pass(rr, rl, 3, SCE_PASS_AO);
- if(srl->passflag & SCE_PASS_ENVIRONMENT)
- render_layer_add_pass(rr, rl, 3, SCE_PASS_ENVIRONMENT);
- if(srl->passflag & SCE_PASS_INDIRECT)
- render_layer_add_pass(rr, rl, 3, SCE_PASS_INDIRECT);
- if(srl->passflag & SCE_PASS_SHADOW)
- render_layer_add_pass(rr, rl, 3, SCE_PASS_SHADOW);
- if(srl->passflag & SCE_PASS_REFLECT)
- render_layer_add_pass(rr, rl, 3, SCE_PASS_REFLECT);
- if(srl->passflag & SCE_PASS_REFRACT)
- render_layer_add_pass(rr, rl, 3, SCE_PASS_REFRACT);
- if(srl->passflag & SCE_PASS_INDEXOB)
- render_layer_add_pass(rr, rl, 1, SCE_PASS_INDEXOB);
- if(srl->passflag & SCE_PASS_INDEXMA)
- render_layer_add_pass(rr, rl, 1, SCE_PASS_INDEXMA);
- if(srl->passflag & SCE_PASS_MIST)
- render_layer_add_pass(rr, rl, 1, SCE_PASS_MIST);
- if(rl->passflag & SCE_PASS_RAYHITS)
- render_layer_add_pass(rr, rl, 4, SCE_PASS_RAYHITS);
-
- }
- /* sss, previewrender and envmap don't do layers, so we make a default one */
- if(rr->layers.first==NULL) {
- rl= MEM_callocN(sizeof(RenderLayer), "new render layer");
- BLI_addtail(&rr->layers, rl);
-
- rl->rectx= rectx;
- rl->recty= recty;
-
- /* duplicate code... */
- if(rr->exrhandle) {
- IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.R", 0, 0, NULL);
- IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.G", 0, 0, NULL);
- IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.B", 0, 0, NULL);
- IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.A", 0, 0, NULL);
- }
- else
- rl->rectf= MEM_mapallocN(rectx*recty*sizeof(float)*4, "Combined rgba");
-
- /* note, this has to be in sync with scene.c */
- rl->lay= (1<<20) -1;
- rl->layflag= 0x7FFF; /* solid ztra halo strand */
- rl->passflag= SCE_PASS_COMBINED;
- FRS_add_freestyle_config( srl );
-
- re->r.actlay= 0;
- }
-
- /* border render; calculate offset for use in compositor. compo is centralized coords */
- rr->xof= re->disprect.xmin + (re->disprect.xmax - re->disprect.xmin)/2 - re->winx/2;
- rr->yof= re->disprect.ymin + (re->disprect.ymax - re->disprect.ymin)/2 - re->winy/2;
+ return render_result_new_from_exr(exrhandle, rectx, recty);
+}
+
+RenderLayer *render_get_active_layer(Render *re, RenderResult *rr)
+{
+ RenderLayer *rl= BLI_findlink(&rr->layers, re->r.actlay);
- return rr;
+ if(rl)
+ return rl;
+ else
+ return rr->layers.first;
}
static int render_scene_needs_vector(Render *re)
@@ -700,344 +237,6 @@ static int render_scene_needs_vector(Render *re)
return 0;
}
-static void do_merge_tile(RenderResult *rr, RenderResult *rrpart, float *target, float *tile, int pixsize)
-{
- int y, ofs, copylen, tilex, tiley;
-
- copylen= tilex= rrpart->rectx;
- tiley= rrpart->recty;
-
- if(rrpart->crop) { /* filters add pixel extra */
- tile+= pixsize*(rrpart->crop + rrpart->crop*tilex);
-
- copylen= tilex - 2*rrpart->crop;
- tiley -= 2*rrpart->crop;
-
- ofs= (rrpart->tilerect.ymin + rrpart->crop)*rr->rectx + (rrpart->tilerect.xmin+rrpart->crop);
- target+= pixsize*ofs;
- }
- else {
- ofs= (rrpart->tilerect.ymin*rr->rectx + rrpart->tilerect.xmin);
- target+= pixsize*ofs;
- }
-
- copylen *= sizeof(float)*pixsize;
- tilex *= pixsize;
- ofs= pixsize*rr->rectx;
-
- for(y=0; y<tiley; y++) {
- memcpy(target, tile, copylen);
- target+= ofs;
- tile+= tilex;
- }
-}
-
-/* used when rendering to a full buffer, or when reading the exr part-layer-pass file */
-/* no test happens here if it fits... we also assume layers are in sync */
-/* is used within threads */
-void merge_render_result(RenderResult *rr, RenderResult *rrpart)
-{
- RenderLayer *rl, *rlp;
- RenderPass *rpass, *rpassp;
-
- for(rl= rr->layers.first, rlp= rrpart->layers.first; rl && rlp; rl= rl->next, rlp= rlp->next) {
-
- /* combined */
- if(rl->rectf && rlp->rectf)
- do_merge_tile(rr, rrpart, rl->rectf, rlp->rectf, 4);
-
- /* passes are allocated in sync */
- for(rpass= rl->passes.first, rpassp= rlp->passes.first; rpass && rpassp; rpass= rpass->next, rpassp= rpassp->next) {
- do_merge_tile(rr, rrpart, rpass->rect, rpassp->rect, rpass->channels);
- }
- }
-}
-
-
-static void save_render_result_tile(RenderResult *rr, RenderResult *rrpart)
-{
- RenderLayer *rlp;
- RenderPass *rpassp;
- int offs, partx, party;
-
- BLI_lock_thread(LOCK_IMAGE);
-
- for(rlp= rrpart->layers.first; rlp; rlp= rlp->next) {
-
- if(rrpart->crop) { /* filters add pixel extra */
- offs= (rrpart->crop + rrpart->crop*rrpart->rectx);
- }
- else {
- offs= 0;
- }
-
- /* combined */
- if(rlp->rectf) {
- int a, xstride= 4;
- for(a=0; a<xstride; a++)
- IMB_exr_set_channel(rr->exrhandle, rlp->name, get_pass_name(SCE_PASS_COMBINED, a),
- xstride, xstride*rrpart->rectx, rlp->rectf+a + xstride*offs);
- }
-
- /* passes are allocated in sync */
- for(rpassp= rlp->passes.first; rpassp; rpassp= rpassp->next) {
- int a, xstride= rpassp->channels;
- for(a=0; a<xstride; a++)
- IMB_exr_set_channel(rr->exrhandle, rlp->name, get_pass_name(rpassp->passtype, a),
- xstride, xstride*rrpart->rectx, rpassp->rect+a + xstride*offs);
- }
-
- }
-
- party= rrpart->tilerect.ymin + rrpart->crop;
- partx= rrpart->tilerect.xmin + rrpart->crop;
- IMB_exrtile_write_channels(rr->exrhandle, partx, party, 0);
-
- BLI_unlock_thread(LOCK_IMAGE);
-
-}
-
-static void save_empty_result_tiles(Render *re)
-{
- RenderPart *pa;
- RenderResult *rr;
-
- for(rr= re->result; rr; rr= rr->next) {
- IMB_exrtile_clear_channels(rr->exrhandle);
-
- for(pa= re->parts.first; pa; pa= pa->next) {
- if(pa->ready==0) {
- int party= pa->disprect.ymin - re->disprect.ymin + pa->crop;
- int partx= pa->disprect.xmin - re->disprect.xmin + pa->crop;
- IMB_exrtile_write_channels(rr->exrhandle, partx, party, 0);
- }
- }
- }
-}
-
-
-/* for passes read from files, these have names stored */
-static char *make_pass_name(RenderPass *rpass, int chan)
-{
- static char name[16];
- int len;
-
- BLI_strncpy(name, rpass->name, EXR_PASS_MAXNAME);
- len= strlen(name);
- name[len]= '.';
- name[len+1]= rpass->chan_id[chan];
- name[len+2]= 0;
-
- return name;
-}
-
-/* filename already made absolute */
-/* called from within UI, saves both rendered result as a file-read result */
-int RE_WriteRenderResult(ReportList *reports, RenderResult *rr, const char *filename, int compress)
-{
- RenderLayer *rl;
- RenderPass *rpass;
- void *exrhandle= IMB_exr_get_handle();
- int success;
-
- BLI_make_existing_file(filename);
-
- /* composite result */
- if(rr->rectf) {
- IMB_exr_add_channel(exrhandle, "Composite", "Combined.R", 4, 4*rr->rectx, rr->rectf);
- IMB_exr_add_channel(exrhandle, "Composite", "Combined.G", 4, 4*rr->rectx, rr->rectf+1);
- IMB_exr_add_channel(exrhandle, "Composite", "Combined.B", 4, 4*rr->rectx, rr->rectf+2);
- IMB_exr_add_channel(exrhandle, "Composite", "Combined.A", 4, 4*rr->rectx, rr->rectf+3);
- }
-
- /* add layers/passes and assign channels */
- for(rl= rr->layers.first; rl; rl= rl->next) {
-
- /* combined */
- if(rl->rectf) {
- int a, xstride= 4;
- for(a=0; a<xstride; a++)
- IMB_exr_add_channel(exrhandle, rl->name, get_pass_name(SCE_PASS_COMBINED, a),
- xstride, xstride*rr->rectx, rl->rectf+a);
- }
-
- /* passes are allocated in sync */
- for(rpass= rl->passes.first; rpass; rpass= rpass->next) {
- int a, xstride= rpass->channels;
- for(a=0; a<xstride; a++) {
- if(rpass->passtype)
- IMB_exr_add_channel(exrhandle, rl->name, get_pass_name(rpass->passtype, a),
- xstride, xstride*rr->rectx, rpass->rect+a);
- else
- IMB_exr_add_channel(exrhandle, rl->name, make_pass_name(rpass, a),
- xstride, xstride*rr->rectx, rpass->rect+a);
- }
- }
- }
-
- /* when the filename has no permissions, this can fail */
- if(IMB_exr_begin_write(exrhandle, filename, rr->rectx, rr->recty, compress)) {
- IMB_exr_write_channels(exrhandle);
- success= TRUE;
- }
- else {
- /* TODO, get the error from openexr's exception */
- BKE_report(reports, RPT_ERROR, "Error Writing Render Result, see console");
- success= FALSE;
- }
- IMB_exr_close(exrhandle);
-
- return success;
-}
-
-/* callbacks for RE_MultilayerConvert */
-static void *ml_addlayer_cb(void *base, char *str)
-{
- RenderResult *rr= base;
- RenderLayer *rl;
-
- rl= MEM_callocN(sizeof(RenderLayer), "new render layer");
- BLI_addtail(&rr->layers, rl);
-
- BLI_strncpy(rl->name, str, EXR_LAY_MAXNAME);
- return rl;
-}
-static void ml_addpass_cb(void *UNUSED(base), void *lay, char *str, float *rect, int totchan, char *chan_id)
-{
- RenderLayer *rl= lay;
- RenderPass *rpass= MEM_callocN(sizeof(RenderPass), "loaded pass");
- int a;
-
- BLI_addtail(&rl->passes, rpass);
- rpass->channels= totchan;
-
- rpass->passtype= passtype_from_name(str);
- if(rpass->passtype==0) printf("unknown pass %s\n", str);
- rl->passflag |= rpass->passtype;
-
- BLI_strncpy(rpass->name, str, EXR_PASS_MAXNAME);
- /* channel id chars */
- for(a=0; a<totchan; a++)
- rpass->chan_id[a]= chan_id[a];
-
- rpass->rect= rect;
-}
-
-/* from imbuf, if a handle was returned we convert this to render result */
-RenderResult *RE_MultilayerConvert(void *exrhandle, int rectx, int recty)
-{
- RenderResult *rr= MEM_callocN(sizeof(RenderResult), "loaded render result");
- RenderLayer *rl;
- RenderPass *rpass;
-
- rr->rectx= rectx;
- rr->recty= recty;
-
- IMB_exr_multilayer_convert(exrhandle, rr, ml_addlayer_cb, ml_addpass_cb);
-
- for(rl=rr->layers.first; rl; rl=rl->next) {
- rl->rectx= rectx;
- rl->recty= recty;
-
- for(rpass=rl->passes.first; rpass; rpass=rpass->next) {
- rpass->rectx= rectx;
- rpass->recty= recty;
- }
- }
-
- return rr;
-}
-
-/* called in end of render, to add names to passes... for UI only */
-static void renderresult_add_names(RenderResult *rr)
-{
- RenderLayer *rl;
- RenderPass *rpass;
-
- for(rl= rr->layers.first; rl; rl= rl->next)
- for(rpass= rl->passes.first; rpass; rpass= rpass->next)
- BLI_strncpy(rpass->name, get_pass_name(rpass->passtype, -1), sizeof(rpass->name));
-}
-
-/* called for reading temp files, and for external engines */
-static int read_render_result_from_file(const char *filename, RenderResult *rr)
-{
- RenderLayer *rl;
- RenderPass *rpass;
- void *exrhandle= IMB_exr_get_handle();
- int rectx, recty;
-
- if(IMB_exr_begin_read(exrhandle, filename, &rectx, &recty)==0) {
- printf("failed being read %s\n", filename);
- IMB_exr_close(exrhandle);
- return 0;
- }
-
- if(rr == NULL || rectx!=rr->rectx || recty!=rr->recty) {
- if(rr)
- printf("error in reading render result: dimensions don't match\n");
- else
- printf("error in reading render result: NULL result pointer\n");
- IMB_exr_close(exrhandle);
- return 0;
- }
- else {
- for(rl= rr->layers.first; rl; rl= rl->next) {
-
- /* combined */
- if(rl->rectf) {
- int a, xstride= 4;
- for(a=0; a<xstride; a++)
- IMB_exr_set_channel(exrhandle, rl->name, get_pass_name(SCE_PASS_COMBINED, a),
- xstride, xstride*rectx, rl->rectf+a);
- }
-
- /* passes are allocated in sync */
- for(rpass= rl->passes.first; rpass; rpass= rpass->next) {
- int a, xstride= rpass->channels;
- for(a=0; a<xstride; a++)
- IMB_exr_set_channel(exrhandle, rl->name, get_pass_name(rpass->passtype, a),
- xstride, xstride*rectx, rpass->rect+a);
- }
-
- }
- IMB_exr_read_channels(exrhandle);
- renderresult_add_names(rr);
- }
-
- IMB_exr_close(exrhandle);
-
- return 1;
-}
-
-/* only for temp buffer files, makes exact copy of render result */
-static int read_render_result(Render *re, int sample)
-{
- char str[FILE_MAX];
- int success;
-
- BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
-
- RE_FreeRenderResult(re->result);
- re->result= new_render_result(re, &re->disprect, 0, RR_USEMEM);
-
- render_unique_exr_name(re, str, sample);
- printf("read exr tmp file: %s\n", str);
-
- if(read_render_result_from_file(str, re->result)) {
- success= TRUE;
- }
- else {
- printf("cannot read: %s\n", str);
- success= FALSE;
-
- }
-
- BLI_rw_mutex_unlock(&re->resultmutex);
-
- return success;
-}
-
/* *************************************************** */
Render *RE_GetRender(const char *name)
@@ -1096,17 +295,6 @@ Scene *RE_GetScene(Render *re)
return NULL;
}
-RenderLayer *render_get_active_layer(Render *re, RenderResult *rr)
-{
- RenderLayer *rl= BLI_findlink(&rr->layers, re->r.actlay);
-
- if(rl)
- return rl;
- else
- return rr->layers.first;
-}
-
-
/* fill provided result struct with what's currently active or done */
void RE_AcquireResultImage(Render *re, RenderResult *rr)
{
@@ -1153,23 +341,7 @@ void RE_ResultGet32(Render *re, unsigned int *rect)
RenderResult rres;
RE_AcquireResultImage(re, &rres);
-
- if(rres.rect32) {
- memcpy(rect, rres.rect32, sizeof(int)*rres.rectx*rres.recty);
- }
- else if(rres.rectf) {
- int profile_from= (re->r.color_mgt_flag & R_COLOR_MANAGEMENT)? IB_PROFILE_LINEAR_RGB: IB_PROFILE_SRGB;
- int predivide= (re->r.color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE);
- int dither= 0;
-
- IMB_buffer_byte_from_float((unsigned char*)rect, rres.rectf,
- 4, dither, IB_PROFILE_SRGB, profile_from, predivide,
- rres.rectx, rres.recty, rres.rectx, rres.rectx);
- }
- else
- /* else fill with black */
- memset(rect, 0, sizeof(int)*re->rectx*re->recty);
-
+ render_result_rect_get_pixels(&rres, &re->r, rect, re->rectx, re->recty);
RE_ReleaseResultImage(re);
}
@@ -1227,8 +399,8 @@ void RE_FreeRender(Render *re)
free_renderdata_tables(re);
free_sample_tables(re);
- RE_FreeRenderResult(re->result);
- RE_FreeRenderResult(re->pushedresult);
+ render_result_free(re->result);
+ render_result_free(re->pushedresult);
BLI_remlink(&RenderGlobal.renderlist, re);
MEM_freeN(re);
@@ -1328,14 +500,14 @@ void RE_InitState(Render *re, Render *source, RenderData *rd, SceneRenderLayer *
if(re->r.scemode & R_PREVIEWBUTS) {
if(re->result && re->result->rectx==re->rectx && re->result->recty==re->recty);
else {
- RE_FreeRenderResult(re->result);
+ render_result_free(re->result);
re->result= NULL;
}
}
else {
/* make empty render result, so display callbacks can initialize */
- RE_FreeRenderResult(re->result);
+ render_result_free(re->result);
re->result= MEM_callocN(sizeof(RenderResult), "new render result");
re->result->rectx= re->rectx;
re->result->recty= re->recty;
@@ -1351,22 +523,6 @@ void RE_InitState(Render *re, Render *source, RenderData *rd, SceneRenderLayer *
RE_init_threadcount(re);
}
-/* part of external api, not called for regular render pipeline */
-void RE_SetDispRect (struct Render *re, rcti *disprect)
-{
- re->disprect= *disprect;
- re->rectx= disprect->xmax-disprect->xmin;
- re->recty= disprect->ymax-disprect->ymin;
-
- /* initialize render result */
- BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
-
- RE_FreeRenderResult(re->result);
- re->result= new_render_result(re, &re->disprect, 0, RR_USEMEM);
-
- BLI_rw_mutex_unlock(&re->resultmutex);
-}
-
void RE_SetWindow(Render *re, rctf *viewplane, float clipsta, float clipend)
{
/* re->ok flag? */
@@ -1461,24 +617,6 @@ static int render_display_draw_enabled(Render *re)
return 1;
}
-/* allocate osa new results for samples */
-static RenderResult *new_full_sample_buffers(Render *re, ListBase *lb, rcti *partrct, int crop)
-{
- int a;
-
- if(re->osa==0)
- return new_render_result(re, partrct, crop, RR_USEMEM);
-
- for(a=0; a<re->osa; a++) {
- RenderResult *rr= new_render_result(re, partrct, crop, RR_USEMEM);
- BLI_addtail(lb, rr);
- rr->sample_nr= a;
- }
-
- return lb->first;
-}
-
-
/* the main thread call, renders an entire part */
static void *do_part_thread(void *pa_v)
{
@@ -1488,9 +626,9 @@ static void *do_part_thread(void *pa_v)
if(R.test_break(R.tbh)==0) {
if(!R.sss_points && (R.r.scemode & R_FULL_SAMPLE))
- pa->result= new_full_sample_buffers(&R, &pa->fullresult, &pa->disprect, pa->crop);
+ pa->result= render_result_new_full_sample(&R, &pa->fullresult, &pa->disprect, pa->crop, RR_USE_MEM);
else
- pa->result= new_render_result(&R, &pa->disprect, pa->crop, RR_USEMEM);
+ pa->result= render_result_new(&R, &pa->disprect, pa->crop, RR_USE_MEM);
if(R.sss_points)
zbufshade_sss_tile(pa);
@@ -1501,16 +639,12 @@ static void *do_part_thread(void *pa_v)
/* merge too on break! */
if(R.result->exrhandle) {
- RenderResult *rr, *rrpart;
-
- for(rr= R.result, rrpart= pa->result; rr && rrpart; rr= rr->next, rrpart= rrpart->next)
- save_render_result_tile(rr, rrpart);
-
+ render_result_exr_file_merge(R.result, pa->result);
}
else if(render_display_draw_enabled(&R)) {
/* on break, don't merge in result for preview renders, looks nicer */
if(R.test_break(R.tbh) && (R.r.scemode & R_PREVIEWBUTS));
- else merge_render_result(R.result, pa->result);
+ else render_result_merge(R.result, pa->result);
}
}
@@ -1634,20 +768,6 @@ static void print_part_stats(Render *re, RenderPart *pa)
re->i.infostr= NULL;
}
-/* make osa new results for samples */
-static RenderResult *new_full_sample_buffers_exr(Render *re)
-{
- int a;
-
- for(a=0; a<re->osa; a++) {
- RenderResult *rr= new_render_result(re, &re->disprect, 0, 1);
- BLI_addtail(&re->fullresult, rr);
- rr->sample_nr= a;
- }
-
- return re->fullresult.first;
-}
-
static void threaded_tile_processor(Render *re)
{
ListBase threads;
@@ -1659,14 +779,15 @@ static void threaded_tile_processor(Render *re)
/* first step; free the entire render result, make new, and/or prepare exr buffer saving */
if(re->result==NULL || !(re->r.scemode & R_PREVIEWBUTS)) {
- RE_FreeRenderResult(re->result);
+ render_result_free(re->result);
if(re->sss_points && render_display_draw_enabled(re))
- re->result= new_render_result(re, &re->disprect, 0, 0);
+ re->result= render_result_new(re, &re->disprect, 0, RR_USE_MEM);
else if(re->r.scemode & R_FULL_SAMPLE)
- re->result= new_full_sample_buffers_exr(re);
+ re->result= render_result_new_full_sample(re, &re->fullresult, &re->disprect, 0, RR_USE_EXR);
else
- re->result= new_render_result(re, &re->disprect, 0, re->r.scemode & (R_EXR_TILE_FILE|R_FULL_SAMPLE));
+ re->result= render_result_new(re, &re->disprect, 0,
+ (re->r.scemode & R_EXR_TILE_FILE)? RR_USE_EXR: RR_USE_MEM);
}
BLI_rw_mutex_unlock(&re->resultmutex);
@@ -1678,17 +799,8 @@ static void threaded_tile_processor(Render *re)
initparts(re);
- if(re->result->exrhandle) {
- RenderResult *rr;
- char str[FILE_MAX];
-
- for(rr= re->result; rr; rr= rr->next) {
- render_unique_exr_name(re, str, rr->sample_nr);
-
- printf("write exr tmp file, %dx%d, %s\n", rr->rectx, rr->recty, str);
- IMB_exrtile_begin_write(rr->exrhandle, str, 0, rr->rectx, rr->recty, re->partx, re->party);
- }
- }
+ if(re->result->exrhandle)
+ render_result_exr_file_begin(re);
BLI_init_threads(&threads, do_part_thread, re->r.threads);
@@ -1742,7 +854,7 @@ static void threaded_tile_processor(Render *re)
re->display_draw(re->ddh, pa->result, NULL);
print_part_stats(re, pa);
- free_render_result(&pa->fullresult, pa->result);
+ render_result_free_list(&pa->fullresult, pa->result);
pa->result= NULL;
re->i.partsdone++;
re->progress(re->prh, re->i.partsdone / (float)re->i.totpart);
@@ -1768,22 +880,9 @@ static void threaded_tile_processor(Render *re)
}
if(re->result->exrhandle) {
- RenderResult *rr;
-
BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
- save_empty_result_tiles(re);
-
- for(rr= re->result; rr; rr= rr->next) {
- IMB_exr_close(rr->exrhandle);
- rr->exrhandle= NULL;
- }
-
- free_render_result(&re->fullresult, re->result);
- re->result= NULL;
-
+ render_result_exr_file_end(re);
BLI_rw_mutex_unlock(&re->resultmutex);
-
- read_render_result(re, 0);
}
/* unset threadsafety */
@@ -1940,7 +1039,7 @@ static void do_render_blur_3d(Render *re)
int blur= re->r.mblur_samples;
/* create accumulation render result */
- rres= new_render_result(re, &re->disprect, 0, RR_USEMEM);
+ rres= render_result_new(re, &re->disprect, 0, RR_USE_MEM);
/* do the blur steps */
while(blur--) {
@@ -1958,7 +1057,7 @@ static void do_render_blur_3d(Render *re)
/* swap results */
BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
- RE_FreeRenderResult(re->result);
+ render_result_free(re->result);
re->result= rres;
BLI_rw_mutex_unlock(&re->resultmutex);
@@ -2065,7 +1164,7 @@ static void do_render_fields_3d(Render *re)
re->disprect.ymax *= 2;
BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
- re->result= new_render_result(re, &re->disprect, 0, RR_USEMEM);
+ re->result= render_result_new(re, &re->disprect, 0, RR_USE_MEM);
if(rr2) {
if(re->r.mode & R_ODDFIELD)
@@ -2073,10 +1172,10 @@ static void do_render_fields_3d(Render *re)
else
merge_renderresult_fields(re->result, rr1, rr2);
- RE_FreeRenderResult(rr2);
+ render_result_free(rr2);
}
- RE_FreeRenderResult(rr1);
+ render_result_free(rr1);
re->i.curfield= 0; /* stats */
@@ -2128,10 +1227,10 @@ static void do_render_fields_blur_3d(Render *re)
re->rectx= re->winx;
re->recty= re->winy;
- rres= new_render_result(re, &re->disprect, 0, RR_USEMEM);
+ rres= render_result_new(re, &re->disprect, 0, RR_USE_MEM);
- merge_render_result(rres, re->result);
- RE_FreeRenderResult(re->result);
+ render_result_merge(rres, re->result);
+ render_result_free(re->result);
re->result= rres;
/* weak... the display callback wants an active renderlayer pointer... */
@@ -2309,7 +1408,7 @@ static void composite_freestyle_renders(Render *re, int sample)
for(srl= (SceneRenderLayer *)re->scene->r.layers.first; srl; srl= srl->next) {
if( FRS_is_freestyle_enabled(srl) ) {
freestyle_render = (Render *)link->data;
- read_render_result(freestyle_render, sample);
+ render_result_exr_file_read(freestyle_render, sample);
FRS_composite_result(re, srl, freestyle_render);
RE_FreeRenderResult(freestyle_render->result);
freestyle_render->result = NULL;
@@ -2375,8 +1474,10 @@ static void do_merge_fullsample(Render *re, bNodeTree *ntree)
if(re1->scene->id.flag & LIB_DOIT) {
if(re1->r.scemode & R_FULL_SAMPLE) {
if(sample) {
- read_render_result(re1, sample);
+ BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
+ render_result_exr_file_read(re1, sample);
composite_freestyle_renders(re1, sample);
+ BLI_rw_mutex_unlock(&re->resultmutex);
}
ntreeCompositTagRender(re1->scene); /* ensure node gets exec to put buffers on stack */
}
@@ -2506,8 +1607,8 @@ static void do_render_composite_fields_blur_3d(Render *re)
/* ensure new result gets added, like for regular renders */
BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
- RE_FreeRenderResult(re->result);
- re->result= new_render_result(re, &re->disprect, 0, RR_USEMEM);
+ render_result_free(re->result);
+ re->result= render_result_new(re, &re->disprect, 0, RR_USE_MEM);
BLI_rw_mutex_unlock(&re->resultmutex);
@@ -2516,8 +1617,11 @@ static void do_render_composite_fields_blur_3d(Render *re)
}
/* swap render result */
- if(re->r.scemode & R_SINGLE_LAYER)
- pop_render_result(re);
+ if(re->r.scemode & R_SINGLE_LAYER) {
+ BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
+ render_result_single_layer_end(re);
+ BLI_rw_mutex_unlock(&re->resultmutex);
+ }
if(!re->test_break(re->tbh)) {
@@ -2614,9 +1718,17 @@ static void do_render_seq(Render * re)
recurs_depth++;
- context = seq_new_render_data(re->main, re->scene,
- re->result->rectx, re->result->recty,
- 100);
+ if((re->r.mode & R_BORDER) && (re->r.mode & R_CROP)==0) {
+ /* if border rendering is used and cropping is disabled, final buffer should
+ be as large as the whole frame */
+ context = seq_new_render_data(re->main, re->scene,
+ re->winx, re->winy,
+ 100);
+ } else {
+ context = seq_new_render_data(re->main, re->scene,
+ re->result->rectx, re->result->recty,
+ 100);
+ }
ibuf = give_ibuf_seq(context, cfra, 0);
@@ -2627,61 +1739,19 @@ static void do_render_seq(Render * re)
BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
if(ibuf) {
- if(ibuf->rect_float) {
- /* color management: when off ensure rectf is non-lin, since thats what the internal
- * render engine delivers */
- int profile_to= (re->r.color_mgt_flag & R_COLOR_MANAGEMENT)? IB_PROFILE_LINEAR_RGB: IB_PROFILE_SRGB;
- int profile_from= (ibuf->profile == IB_PROFILE_LINEAR_RGB)? IB_PROFILE_LINEAR_RGB: IB_PROFILE_SRGB;
- int predivide= (re->r.color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE);
-
- if (!rr->rectf)
- rr->rectf= MEM_mallocN(4*sizeof(float)*rr->rectx*rr->recty, "render_seq rectf");
-
- IMB_buffer_float_from_float(rr->rectf, ibuf->rect_float,
- 4, profile_to, profile_from, predivide,
- rr->rectx, rr->recty, rr->rectx, rr->rectx);
-
- /* TSK! Since sequence render doesn't free the *rr render result, the old rect32
- can hang around when sequence render has rendered a 32 bits one before */
- if(rr->rect32) {
- MEM_freeN(rr->rect32);
- rr->rect32= NULL;
- }
- }
- else if(ibuf->rect) {
- if (!rr->rect32)
- rr->rect32= MEM_mallocN(sizeof(int)*rr->rectx*rr->recty, "render_seq rect");
-
- memcpy(rr->rect32, ibuf->rect, 4*rr->rectx*rr->recty);
-
- /* if (ibuf->zbuf) { */
- /* if (R.rectz) freeN(R.rectz); */
- /* R.rectz = BLI_dupallocN(ibuf->zbuf); */
- /* } */
-
- /* Same things as above, old rectf can hang around from previous render. */
- if(rr->rectf) {
- MEM_freeN(rr->rectf);
- rr->rectf= NULL;
- }
- }
+ /* copy ibuf into combined pixel rect */
+ render_result_rect_from_ibuf(rr, &re->r, ibuf);
if (recurs_depth == 0) { /* with nested scenes, only free on toplevel... */
Editing * ed = re->scene->ed;
- if (ed) {
+ if (ed)
free_imbuf_seq(re->scene, &ed->seqbase, TRUE, TRUE);
- }
}
IMB_freeImBuf(ibuf);
}
else {
/* render result is delivered empty in most cases, nevertheless we handle all cases */
- if (rr->rectf)
- memset(rr->rectf, 0, 4*sizeof(float)*rr->rectx*rr->recty);
- else if (rr->rect32)
- memset(rr->rect32, 0, 4*rr->rectx*rr->recty);
- else
- rr->rect32= MEM_callocN(sizeof(int)*rr->rectx*rr->recty, "render_seq rect");
+ render_result_rect_fill_zero(rr);
}
BLI_rw_mutex_unlock(&re->resultmutex);
@@ -2723,11 +1793,6 @@ static void do_render_all_options(Render *re)
do_render_composite_fields_blur_3d(re);
}
- /* for UI only */
- BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
- renderresult_add_names(re->result);
- BLI_rw_mutex_unlock(&re->resultmutex);
-
re->i.lastframetime= PIL_check_seconds_timer()- re->i.starttime;
re->stats_draw(re->sdh, &re->i);
@@ -2811,7 +1876,7 @@ int RE_is_rendering_allowed(Scene *scene, Object *camera_override, ReportList *r
if(scene->r.scemode & (R_EXR_TILE_FILE|R_FULL_SAMPLE)) {
char str[FILE_MAX];
- scene_unique_exr_name(scene, str, 0);
+ render_result_exr_file_path(scene, 0, str);
if (BLI_file_is_writable(str)==0) {
BKE_report(reports, RPT_ERROR, "Can not save render buffers, check the temp default path");
@@ -2973,8 +2038,11 @@ static int render_initialize_from_main(Render *re, Main *bmain, Scene *scene, Sc
update_physics_cache(re, scene, anim_init);
}
- if(srl || scene->r.scemode & R_SINGLE_LAYER)
- push_render_result(re);
+ if(srl || scene->r.scemode & R_SINGLE_LAYER) {
+ BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
+ render_result_single_layer_begin(re);
+ BLI_rw_mutex_unlock(&re->resultmutex);
+ }
RE_InitState(re, NULL, &scene->r, srl, winx, winy, &disprect);
if(!re->ok) /* if an error was printed, abort */
@@ -3080,37 +2148,7 @@ static int do_write_image_or_movie(Render *re, Main *bmain, Scene *scene, bMovie
}
}
else {
- int flags = (scene->r.color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE)? IB_cm_predivide: 0;
- ImBuf *ibuf= IMB_allocImBuf(rres.rectx, rres.recty, scene->r.im_format.planes, flags);
-
- /* if not exists, BKE_write_ibuf makes one */
- ibuf->rect= (unsigned int *)rres.rect32;
- ibuf->rect_float= rres.rectf;
- ibuf->zbuf_float= rres.rectz;
-
- /* float factor for random dither, imbuf takes care of it */
- ibuf->dither= scene->r.dither_intensity;
-
- /* prepare to gamma correct to sRGB color space */
- if (scene->r.color_mgt_flag & R_COLOR_MANAGEMENT) {
- /* sequence editor can generate 8bpc render buffers */
- if (ibuf->rect) {
- ibuf->profile = IB_PROFILE_SRGB;
- if (BKE_imtype_valid_depths(scene->r.im_format.imtype) & (R_IMF_CHAN_DEPTH_12|R_IMF_CHAN_DEPTH_16|R_IMF_CHAN_DEPTH_24|R_IMF_CHAN_DEPTH_32))
- IMB_float_from_rect(ibuf);
- } else {
- ibuf->profile = IB_PROFILE_LINEAR_RGB;
- }
- }
-
- /* color -> greyscale */
- /* editing directly would alter the render view */
- if(scene->r.im_format.planes == R_IMF_PLANES_BW) {
- ImBuf *ibuf_bw= IMB_dupImBuf(ibuf);
- IMB_color_to_bw(ibuf_bw);
- IMB_freeImBuf(ibuf);
- ibuf= ibuf_bw;
- }
+ ImBuf *ibuf= render_result_rect_to_ibuf(&rres, &scene->r);
ok= BKE_write_ibuf_stamp(scene, camera, ibuf, name, &scene->r.im_format);
@@ -3309,7 +2347,7 @@ void RE_PreviewRender(Render *re, Main *bmain, Scene *sce)
int RE_ReadRenderResult(Scene *scene, Scene *scenode)
{
Render *re;
- int winx, winy;
+ int winx, winy, success;
rcti disprect;
/* calculate actual render result and display size */
@@ -3340,7 +2378,11 @@ int RE_ReadRenderResult(Scene *scene, Scene *scenode)
RE_InitState(re, NULL, &scene->r, NULL, winx, winy, &disprect);
re->scene= scene;
- return read_render_result(re, 0);
+ BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
+ success= render_result_exr_file_read(re, 0);
+ BLI_rw_mutex_unlock(&re->resultmutex);
+
+ return success;
}
void RE_set_max_threads(int threads)
@@ -3407,7 +2449,7 @@ void RE_layer_load_from_file(RenderLayer *layer, ReportList *reports, const char
void RE_result_load_from_file(RenderResult *result, ReportList *reports, const char *filename)
{
- if(!read_render_result_from_file(filename, result)) {
+ if(!render_result_exr_file_read_path(result, filename)) {
BKE_reportf(reports, RPT_ERROR, "RE_result_rect_from_file: failed to load '%s'\n", filename);
return;
}
diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c
index 41bfcb55068..f9ffc2532eb 100644
--- a/source/blender/render/intern/source/rayshade.c
+++ b/source/blender/render/intern/source/rayshade.c
@@ -53,6 +53,7 @@
#include "PIL_time.h"
+#include "render_result.h"
#include "render_types.h"
#include "renderpipeline.h"
#include "rendercore.h"
@@ -779,7 +780,10 @@ static void traceray(ShadeInput *origshi, ShadeResult *origshr, short depth, con
tracol[3]= col[3]; // we pass on and accumulate alpha
if((shi.mat->mode & MA_TRANSP) && (shi.mat->mode & MA_RAYTRANSP)) {
- if(traflag & RAY_INSIDE) {
+ /* don't overwrite traflag, it's value is used in mirror reflection */
+ int new_traflag = traflag;
+
+ if(new_traflag & RAY_INSIDE) {
/* inside the material, so use inverse normal */
float norm[3];
norm[0]= - shi.vn[0];
@@ -788,7 +792,7 @@ static void traceray(ShadeInput *origshi, ShadeResult *origshr, short depth, con
if (refraction(refract, norm, shi.view, shi.ang)) {
/* ray comes out from the material into air */
- traflag &= ~RAY_INSIDE;
+ new_traflag &= ~RAY_INSIDE;
}
else {
/* total internal reflection (ray stays inside the material) */
@@ -798,14 +802,14 @@ static void traceray(ShadeInput *origshi, ShadeResult *origshr, short depth, con
else {
if (refraction(refract, shi.vn, shi.view, shi.ang)) {
/* ray goes in to the material from air */
- traflag |= RAY_INSIDE;
+ new_traflag |= RAY_INSIDE;
}
else {
/* total external reflection (ray doesn't enter the material) */
reflection(refract, shi.vn, shi.view, shi.vn);
}
}
- traceray(origshi, origshr, depth-1, shi.co, refract, tracol, shi.obi, shi.vlr, traflag);
+ traceray(origshi, origshr, depth-1, shi.co, refract, tracol, shi.obi, shi.vlr, new_traflag);
}
else
traceray(origshi, origshr, depth-1, shi.co, shi.view, tracol, shi.obi, shi.vlr, 0);
@@ -839,7 +843,7 @@ static void traceray(ShadeInput *origshi, ShadeResult *origshr, short depth, con
float ref[3];
reflection_simple(ref, shi.vn, shi.view);
- traceray(origshi, origshr, depth-1, shi.co, ref, mircol, shi.obi, shi.vlr, 0);
+ traceray(origshi, origshr, depth-1, shi.co, ref, mircol, shi.obi, shi.vlr, traflag);
f1= 1.0f-f;
diff --git a/source/blender/render/intern/source/render_result.c b/source/blender/render/intern/source/render_result.c
new file mode 100644
index 00000000000..a8a74daa47b
--- /dev/null
+++ b/source/blender/render/intern/source/render_result.c
@@ -0,0 +1,1024 @@
+/*
+ *
+ * ***** 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) 2006 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/render/intern/source/render_result.c
+ * \ingroup render
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "BKE_image.h"
+#include "BKE_global.h"
+#include "BKE_main.h"
+#include "BKE_report.h"
+#include "BKE_utildefines.h"
+
+#include "BLI_fileops.h"
+#include "BLI_listbase.h"
+#include "BLI_path_util.h"
+#include "BLI_string.h"
+#include "BLI_threads.h"
+#include "BLI_utildefines.h"
+
+#include "IMB_imbuf.h"
+#include "IMB_imbuf_types.h"
+
+#include "intern/openexr/openexr_multi.h"
+
+#include "render_result.h"
+#include "render_types.h"
+
+#include "FRS_freestyle_config.h"
+
+/********************************** Free *************************************/
+
+void render_result_free(RenderResult *res)
+{
+ if(res==NULL) return;
+
+ while(res->layers.first) {
+ RenderLayer *rl= res->layers.first;
+
+ if(rl->rectf) MEM_freeN(rl->rectf);
+ /* acolrect and scolrect are optionally allocated in shade_tile, only free here since it can be used for drawing */
+ if(rl->acolrect) MEM_freeN(rl->acolrect);
+ if(rl->scolrect) MEM_freeN(rl->scolrect);
+
+ while(rl->passes.first) {
+ RenderPass *rpass= rl->passes.first;
+ if(rpass->rect) MEM_freeN(rpass->rect);
+ BLI_remlink(&rl->passes, rpass);
+ MEM_freeN(rpass);
+ }
+ BLI_remlink(&res->layers, rl);
+ MEM_freeN(rl);
+ }
+
+ if(res->rect32)
+ MEM_freeN(res->rect32);
+ if(res->rectz)
+ MEM_freeN(res->rectz);
+ if(res->rectf)
+ MEM_freeN(res->rectf);
+ if(res->text)
+ MEM_freeN(res->text);
+
+ MEM_freeN(res);
+}
+
+/* version that's compatible with fullsample buffers */
+void render_result_free_list(ListBase *lb, RenderResult *rr)
+{
+ RenderResult *rrnext;
+
+ for(; rr; rr= rrnext) {
+ rrnext= rr->next;
+
+ if(lb && lb->first)
+ BLI_remlink(lb, rr);
+
+ render_result_free(rr);
+ }
+}
+
+/********************************* Names *************************************/
+
+/* NOTE: OpenEXR only supports 32 chars for layer+pass names
+ In blender we now use max 10 chars for pass, max 20 for layer */
+static const char *get_pass_name(int passtype, int channel)
+{
+
+ if(passtype == SCE_PASS_COMBINED) {
+ if(channel==-1) return "Combined";
+ if(channel==0) return "Combined.R";
+ if(channel==1) return "Combined.G";
+ if(channel==2) return "Combined.B";
+ return "Combined.A";
+ }
+ if(passtype == SCE_PASS_Z) {
+ if(channel==-1) return "Depth";
+ return "Depth.Z";
+ }
+ if(passtype == SCE_PASS_VECTOR) {
+ if(channel==-1) return "Vector";
+ if(channel==0) return "Vector.X";
+ if(channel==1) return "Vector.Y";
+ if(channel==2) return "Vector.Z";
+ return "Vector.W";
+ }
+ if(passtype == SCE_PASS_NORMAL) {
+ if(channel==-1) return "Normal";
+ if(channel==0) return "Normal.X";
+ if(channel==1) return "Normal.Y";
+ return "Normal.Z";
+ }
+ if(passtype == SCE_PASS_UV) {
+ if(channel==-1) return "UV";
+ if(channel==0) return "UV.U";
+ if(channel==1) return "UV.V";
+ return "UV.A";
+ }
+ if(passtype == SCE_PASS_RGBA) {
+ if(channel==-1) return "Color";
+ if(channel==0) return "Color.R";
+ if(channel==1) return "Color.G";
+ if(channel==2) return "Color.B";
+ return "Color.A";
+ }
+ if(passtype == SCE_PASS_EMIT) {
+ if(channel==-1) return "Emit";
+ if(channel==0) return "Emit.R";
+ if(channel==1) return "Emit.G";
+ return "Emit.B";
+ }
+ if(passtype == SCE_PASS_DIFFUSE) {
+ if(channel==-1) return "Diffuse";
+ if(channel==0) return "Diffuse.R";
+ if(channel==1) return "Diffuse.G";
+ return "Diffuse.B";
+ }
+ if(passtype == SCE_PASS_SPEC) {
+ if(channel==-1) return "Spec";
+ if(channel==0) return "Spec.R";
+ if(channel==1) return "Spec.G";
+ return "Spec.B";
+ }
+ if(passtype == SCE_PASS_SHADOW) {
+ if(channel==-1) return "Shadow";
+ if(channel==0) return "Shadow.R";
+ if(channel==1) return "Shadow.G";
+ return "Shadow.B";
+ }
+ if(passtype == SCE_PASS_AO) {
+ if(channel==-1) return "AO";
+ if(channel==0) return "AO.R";
+ if(channel==1) return "AO.G";
+ return "AO.B";
+ }
+ if(passtype == SCE_PASS_ENVIRONMENT) {
+ if(channel==-1) return "Env";
+ if(channel==0) return "Env.R";
+ if(channel==1) return "Env.G";
+ return "Env.B";
+ }
+ if(passtype == SCE_PASS_INDIRECT) {
+ if(channel==-1) return "Indirect";
+ if(channel==0) return "Indirect.R";
+ if(channel==1) return "Indirect.G";
+ return "Indirect.B";
+ }
+ if(passtype == SCE_PASS_REFLECT) {
+ if(channel==-1) return "Reflect";
+ if(channel==0) return "Reflect.R";
+ if(channel==1) return "Reflect.G";
+ return "Reflect.B";
+ }
+ if(passtype == SCE_PASS_REFRACT) {
+ if(channel==-1) return "Refract";
+ if(channel==0) return "Refract.R";
+ if(channel==1) return "Refract.G";
+ return "Refract.B";
+ }
+ if(passtype == SCE_PASS_INDEXOB) {
+ if(channel==-1) return "IndexOB";
+ return "IndexOB.X";
+ }
+ if(passtype == SCE_PASS_INDEXMA) {
+ if(channel==-1) return "IndexMA";
+ return "IndexMA.X";
+ }
+ if(passtype == SCE_PASS_MIST) {
+ if(channel==-1) return "Mist";
+ return "Mist.Z";
+ }
+ if(passtype == SCE_PASS_RAYHITS)
+ {
+ if(channel==-1) return "Rayhits";
+ if(channel==0) return "Rayhits.R";
+ if(channel==1) return "Rayhits.G";
+ return "Rayhits.B";
+ }
+ return "Unknown";
+}
+
+static int passtype_from_name(const char *str)
+{
+
+ if(strcmp(str, "Combined")==0)
+ return SCE_PASS_COMBINED;
+
+ if(strcmp(str, "Depth")==0)
+ return SCE_PASS_Z;
+
+ if(strcmp(str, "Vector")==0)
+ return SCE_PASS_VECTOR;
+
+ if(strcmp(str, "Normal")==0)
+ return SCE_PASS_NORMAL;
+
+ if(strcmp(str, "UV")==0)
+ return SCE_PASS_UV;
+
+ if(strcmp(str, "Color")==0)
+ return SCE_PASS_RGBA;
+
+ if(strcmp(str, "Emit")==0)
+ return SCE_PASS_EMIT;
+
+ if(strcmp(str, "Diffuse")==0)
+ return SCE_PASS_DIFFUSE;
+
+ if(strcmp(str, "Spec")==0)
+ return SCE_PASS_SPEC;
+
+ if(strcmp(str, "Shadow")==0)
+ return SCE_PASS_SHADOW;
+
+ if(strcmp(str, "AO")==0)
+ return SCE_PASS_AO;
+
+ if(strcmp(str, "Env")==0)
+ return SCE_PASS_ENVIRONMENT;
+
+ if(strcmp(str, "Indirect")==0)
+ return SCE_PASS_INDIRECT;
+
+ if(strcmp(str, "Reflect")==0)
+ return SCE_PASS_REFLECT;
+
+ if(strcmp(str, "Refract")==0)
+ return SCE_PASS_REFRACT;
+
+ if(strcmp(str, "IndexOB")==0)
+ return SCE_PASS_INDEXOB;
+
+ if(strcmp(str, "IndexMA")==0)
+ return SCE_PASS_INDEXMA;
+
+ if(strcmp(str, "Mist")==0)
+ return SCE_PASS_MIST;
+
+ if(strcmp(str, "RayHits")==0)
+ return SCE_PASS_RAYHITS;
+ return 0;
+}
+
+/********************************** New **************************************/
+
+static void render_layer_add_pass(RenderResult *rr, RenderLayer *rl, int channels, int passtype)
+{
+ const char *typestr= get_pass_name(passtype, 0);
+ RenderPass *rpass= MEM_callocN(sizeof(RenderPass), typestr);
+ int rectsize= rr->rectx*rr->recty*channels;
+
+ BLI_addtail(&rl->passes, rpass);
+ rpass->passtype= passtype;
+ rpass->channels= channels;
+ rpass->rectx= rl->rectx;
+ rpass->recty= rl->recty;
+ BLI_strncpy(rpass->name, get_pass_name(rpass->passtype, -1), sizeof(rpass->name));
+
+ if(rr->exrhandle) {
+ int a;
+ for(a=0; a<channels; a++)
+ IMB_exr_add_channel(rr->exrhandle, rl->name, get_pass_name(passtype, a), 0, 0, NULL);
+ }
+ else {
+ float *rect;
+ int x;
+
+ rpass->rect= MEM_mapallocN(sizeof(float)*rectsize, typestr);
+
+ if(passtype==SCE_PASS_VECTOR) {
+ /* initialize to max speed */
+ rect= rpass->rect;
+ for(x= rectsize-1; x>=0; x--)
+ rect[x]= PASS_VECTOR_MAX;
+ }
+ else if(passtype==SCE_PASS_Z) {
+ rect= rpass->rect;
+ for(x= rectsize-1; x>=0; x--)
+ rect[x]= 10e10;
+ }
+ }
+}
+
+/* called by main render as well for parts */
+/* will read info from Render *re to define layers */
+/* called in threads */
+/* re->winx,winy is coordinate space of entire image, partrct the part within */
+RenderResult *render_result_new(Render *re, rcti *partrct, int crop, int savebuffers)
+{
+ RenderResult *rr;
+ RenderLayer *rl;
+ SceneRenderLayer *srl;
+ int rectx, recty, nr;
+
+ rectx= partrct->xmax - partrct->xmin;
+ recty= partrct->ymax - partrct->ymin;
+
+ if(rectx<=0 || recty<=0)
+ return NULL;
+
+ rr= MEM_callocN(sizeof(RenderResult), "new render result");
+ rr->rectx= rectx;
+ rr->recty= recty;
+ rr->renrect.xmin= 0; rr->renrect.xmax= rectx-2*crop;
+ /* crop is one or two extra pixels rendered for filtering, is used for merging and display too */
+ rr->crop= crop;
+
+ /* tilerect is relative coordinates within render disprect. do not subtract crop yet */
+ rr->tilerect.xmin= partrct->xmin - re->disprect.xmin;
+ rr->tilerect.xmax= partrct->xmax - re->disprect.xmax;
+ rr->tilerect.ymin= partrct->ymin - re->disprect.ymin;
+ rr->tilerect.ymax= partrct->ymax - re->disprect.ymax;
+
+ if(savebuffers) {
+ rr->exrhandle= IMB_exr_get_handle();
+ }
+
+ /* check renderdata for amount of layers */
+ for(nr=0, srl= re->r.layers.first; srl; srl= srl->next, nr++) {
+
+ if((re->r.scemode & R_SINGLE_LAYER) && nr!=re->r.actlay)
+ continue;
+ if(srl->layflag & SCE_LAY_DISABLE)
+ continue;
+
+ rl= MEM_callocN(sizeof(RenderLayer), "new render layer");
+ BLI_addtail(&rr->layers, rl);
+
+ BLI_strncpy(rl->name, srl->name, sizeof(rl->name));
+ rl->lay= srl->lay;
+ rl->lay_zmask= srl->lay_zmask;
+ rl->layflag= srl->layflag;
+ rl->passflag= srl->passflag; // for debugging: srl->passflag|SCE_PASS_RAYHITS;
+ rl->pass_xor= srl->pass_xor;
+ rl->light_override= srl->light_override;
+ rl->mat_override= srl->mat_override;
+ rl->rectx= rectx;
+ rl->recty= recty;
+
+ if(rr->exrhandle) {
+ IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.R", 0, 0, NULL);
+ IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.G", 0, 0, NULL);
+ IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.B", 0, 0, NULL);
+ IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.A", 0, 0, NULL);
+ }
+ else
+ rl->rectf= MEM_mapallocN(rectx*recty*sizeof(float)*4, "Combined rgba");
+
+ if(srl->passflag & SCE_PASS_Z)
+ render_layer_add_pass(rr, rl, 1, SCE_PASS_Z);
+ if(srl->passflag & SCE_PASS_VECTOR)
+ render_layer_add_pass(rr, rl, 4, SCE_PASS_VECTOR);
+ if(srl->passflag & SCE_PASS_NORMAL)
+ render_layer_add_pass(rr, rl, 3, SCE_PASS_NORMAL);
+ if(srl->passflag & SCE_PASS_UV)
+ render_layer_add_pass(rr, rl, 3, SCE_PASS_UV);
+ if(srl->passflag & SCE_PASS_RGBA)
+ render_layer_add_pass(rr, rl, 4, SCE_PASS_RGBA);
+ if(srl->passflag & SCE_PASS_EMIT)
+ render_layer_add_pass(rr, rl, 3, SCE_PASS_EMIT);
+ if(srl->passflag & SCE_PASS_DIFFUSE)
+ render_layer_add_pass(rr, rl, 3, SCE_PASS_DIFFUSE);
+ if(srl->passflag & SCE_PASS_SPEC)
+ render_layer_add_pass(rr, rl, 3, SCE_PASS_SPEC);
+ if(srl->passflag & SCE_PASS_AO)
+ render_layer_add_pass(rr, rl, 3, SCE_PASS_AO);
+ if(srl->passflag & SCE_PASS_ENVIRONMENT)
+ render_layer_add_pass(rr, rl, 3, SCE_PASS_ENVIRONMENT);
+ if(srl->passflag & SCE_PASS_INDIRECT)
+ render_layer_add_pass(rr, rl, 3, SCE_PASS_INDIRECT);
+ if(srl->passflag & SCE_PASS_SHADOW)
+ render_layer_add_pass(rr, rl, 3, SCE_PASS_SHADOW);
+ if(srl->passflag & SCE_PASS_REFLECT)
+ render_layer_add_pass(rr, rl, 3, SCE_PASS_REFLECT);
+ if(srl->passflag & SCE_PASS_REFRACT)
+ render_layer_add_pass(rr, rl, 3, SCE_PASS_REFRACT);
+ if(srl->passflag & SCE_PASS_INDEXOB)
+ render_layer_add_pass(rr, rl, 1, SCE_PASS_INDEXOB);
+ if(srl->passflag & SCE_PASS_INDEXMA)
+ render_layer_add_pass(rr, rl, 1, SCE_PASS_INDEXMA);
+ if(srl->passflag & SCE_PASS_MIST)
+ render_layer_add_pass(rr, rl, 1, SCE_PASS_MIST);
+ if(rl->passflag & SCE_PASS_RAYHITS)
+ render_layer_add_pass(rr, rl, 4, SCE_PASS_RAYHITS);
+
+ }
+ /* sss, previewrender and envmap don't do layers, so we make a default one */
+ if(rr->layers.first==NULL) {
+ rl= MEM_callocN(sizeof(RenderLayer), "new render layer");
+ BLI_addtail(&rr->layers, rl);
+
+ rl->rectx= rectx;
+ rl->recty= recty;
+
+ /* duplicate code... */
+ if(rr->exrhandle) {
+ IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.R", 0, 0, NULL);
+ IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.G", 0, 0, NULL);
+ IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.B", 0, 0, NULL);
+ IMB_exr_add_channel(rr->exrhandle, rl->name, "Combined.A", 0, 0, NULL);
+ }
+ else
+ rl->rectf= MEM_mapallocN(rectx*recty*sizeof(float)*4, "Combined rgba");
+
+ /* note, this has to be in sync with scene.c */
+ rl->lay= (1<<20) -1;
+ rl->layflag= 0x7FFF; /* solid ztra halo strand */
+ rl->passflag= SCE_PASS_COMBINED;
+ FRS_add_freestyle_config( srl );
+
+ re->r.actlay= 0;
+ }
+
+ /* border render; calculate offset for use in compositor. compo is centralized coords */
+ rr->xof= re->disprect.xmin + (re->disprect.xmax - re->disprect.xmin)/2 - re->winx/2;
+ rr->yof= re->disprect.ymin + (re->disprect.ymax - re->disprect.ymin)/2 - re->winy/2;
+
+ return rr;
+}
+
+/* allocate osa new results for samples */
+RenderResult *render_result_new_full_sample(Render *re, ListBase *lb, rcti *partrct, int crop, int savebuffers)
+{
+ int a;
+
+ if(re->osa==0)
+ return render_result_new(re, partrct, crop, savebuffers);
+
+ for(a=0; a<re->osa; a++) {
+ RenderResult *rr= render_result_new(re, partrct, crop, savebuffers);
+ BLI_addtail(lb, rr);
+ rr->sample_nr= a;
+ }
+
+ return lb->first;
+}
+
+/* callbacks for render_result_new_from_exr */
+static void *ml_addlayer_cb(void *base, char *str)
+{
+ RenderResult *rr= base;
+ RenderLayer *rl;
+
+ rl= MEM_callocN(sizeof(RenderLayer), "new render layer");
+ BLI_addtail(&rr->layers, rl);
+
+ BLI_strncpy(rl->name, str, EXR_LAY_MAXNAME);
+ return rl;
+}
+
+static void ml_addpass_cb(void *UNUSED(base), void *lay, char *str, float *rect, int totchan, char *chan_id)
+{
+ RenderLayer *rl= lay;
+ RenderPass *rpass= MEM_callocN(sizeof(RenderPass), "loaded pass");
+ int a;
+
+ BLI_addtail(&rl->passes, rpass);
+ rpass->channels= totchan;
+
+ rpass->passtype= passtype_from_name(str);
+ if(rpass->passtype==0) printf("unknown pass %s\n", str);
+ rl->passflag |= rpass->passtype;
+
+ BLI_strncpy(rpass->name, str, EXR_PASS_MAXNAME);
+ /* channel id chars */
+ for(a=0; a<totchan; a++)
+ rpass->chan_id[a]= chan_id[a];
+
+ rpass->rect= rect;
+}
+
+/* from imbuf, if a handle was returned we convert this to render result */
+RenderResult *render_result_new_from_exr(void *exrhandle, int rectx, int recty)
+{
+ RenderResult *rr= MEM_callocN(sizeof(RenderResult), "loaded render result");
+ RenderLayer *rl;
+ RenderPass *rpass;
+
+ rr->rectx= rectx;
+ rr->recty= recty;
+
+ IMB_exr_multilayer_convert(exrhandle, rr, ml_addlayer_cb, ml_addpass_cb);
+
+ for(rl=rr->layers.first; rl; rl=rl->next) {
+ rl->rectx= rectx;
+ rl->recty= recty;
+
+ for(rpass=rl->passes.first; rpass; rpass=rpass->next) {
+ rpass->rectx= rectx;
+ rpass->recty= recty;
+ }
+ }
+
+ return rr;
+}
+
+/*********************************** Merge ***********************************/
+
+static void do_merge_tile(RenderResult *rr, RenderResult *rrpart, float *target, float *tile, int pixsize)
+{
+ int y, ofs, copylen, tilex, tiley;
+
+ copylen= tilex= rrpart->rectx;
+ tiley= rrpart->recty;
+
+ if(rrpart->crop) { /* filters add pixel extra */
+ tile+= pixsize*(rrpart->crop + rrpart->crop*tilex);
+
+ copylen= tilex - 2*rrpart->crop;
+ tiley -= 2*rrpart->crop;
+
+ ofs= (rrpart->tilerect.ymin + rrpart->crop)*rr->rectx + (rrpart->tilerect.xmin+rrpart->crop);
+ target+= pixsize*ofs;
+ }
+ else {
+ ofs= (rrpart->tilerect.ymin*rr->rectx + rrpart->tilerect.xmin);
+ target+= pixsize*ofs;
+ }
+
+ copylen *= sizeof(float)*pixsize;
+ tilex *= pixsize;
+ ofs= pixsize*rr->rectx;
+
+ for(y=0; y<tiley; y++) {
+ memcpy(target, tile, copylen);
+ target+= ofs;
+ tile+= tilex;
+ }
+}
+
+/* used when rendering to a full buffer, or when reading the exr part-layer-pass file */
+/* no test happens here if it fits... we also assume layers are in sync */
+/* is used within threads */
+void render_result_merge(RenderResult *rr, RenderResult *rrpart)
+{
+ RenderLayer *rl, *rlp;
+ RenderPass *rpass, *rpassp;
+
+ for(rl= rr->layers.first, rlp= rrpart->layers.first; rl && rlp; rl= rl->next, rlp= rlp->next) {
+
+ /* combined */
+ if(rl->rectf && rlp->rectf)
+ do_merge_tile(rr, rrpart, rl->rectf, rlp->rectf, 4);
+
+ /* passes are allocated in sync */
+ for(rpass= rl->passes.first, rpassp= rlp->passes.first; rpass && rpassp; rpass= rpass->next, rpassp= rpassp->next) {
+ do_merge_tile(rr, rrpart, rpass->rect, rpassp->rect, rpass->channels);
+ }
+ }
+}
+
+/* for passes read from files, these have names stored */
+static char *make_pass_name(RenderPass *rpass, int chan)
+{
+ static char name[16];
+ int len;
+
+ BLI_strncpy(name, rpass->name, EXR_PASS_MAXNAME);
+ len= strlen(name);
+ name[len]= '.';
+ name[len+1]= rpass->chan_id[chan];
+ name[len+2]= 0;
+
+ return name;
+}
+
+/* filename already made absolute */
+/* called from within UI, saves both rendered result as a file-read result */
+int RE_WriteRenderResult(ReportList *reports, RenderResult *rr, const char *filename, int compress)
+{
+ RenderLayer *rl;
+ RenderPass *rpass;
+ void *exrhandle= IMB_exr_get_handle();
+ int success;
+
+ BLI_make_existing_file(filename);
+
+ /* composite result */
+ if(rr->rectf) {
+ IMB_exr_add_channel(exrhandle, "Composite", "Combined.R", 4, 4*rr->rectx, rr->rectf);
+ IMB_exr_add_channel(exrhandle, "Composite", "Combined.G", 4, 4*rr->rectx, rr->rectf+1);
+ IMB_exr_add_channel(exrhandle, "Composite", "Combined.B", 4, 4*rr->rectx, rr->rectf+2);
+ IMB_exr_add_channel(exrhandle, "Composite", "Combined.A", 4, 4*rr->rectx, rr->rectf+3);
+ }
+
+ /* add layers/passes and assign channels */
+ for(rl= rr->layers.first; rl; rl= rl->next) {
+
+ /* combined */
+ if(rl->rectf) {
+ int a, xstride= 4;
+ for(a=0; a<xstride; a++)
+ IMB_exr_add_channel(exrhandle, rl->name, get_pass_name(SCE_PASS_COMBINED, a),
+ xstride, xstride*rr->rectx, rl->rectf+a);
+ }
+
+ /* passes are allocated in sync */
+ for(rpass= rl->passes.first; rpass; rpass= rpass->next) {
+ int a, xstride= rpass->channels;
+ for(a=0; a<xstride; a++) {
+ if(rpass->passtype)
+ IMB_exr_add_channel(exrhandle, rl->name, get_pass_name(rpass->passtype, a),
+ xstride, xstride*rr->rectx, rpass->rect+a);
+ else
+ IMB_exr_add_channel(exrhandle, rl->name, make_pass_name(rpass, a),
+ xstride, xstride*rr->rectx, rpass->rect+a);
+ }
+ }
+ }
+
+ /* when the filename has no permissions, this can fail */
+ if(IMB_exr_begin_write(exrhandle, filename, rr->rectx, rr->recty, compress)) {
+ IMB_exr_write_channels(exrhandle);
+ success= TRUE;
+ }
+ else {
+ /* TODO, get the error from openexr's exception */
+ BKE_report(reports, RPT_ERROR, "Error Writing Render Result, see console");
+ success= FALSE;
+ }
+ IMB_exr_close(exrhandle);
+
+ return success;
+}
+
+/**************************** Single Layer Rendering *************************/
+
+void render_result_single_layer_begin(Render *re)
+{
+ /* all layers except the active one get temporally pushed away */
+
+ /* officially pushed result should be NULL... error can happen with do_seq */
+ RE_FreeRenderResult(re->pushedresult);
+
+ re->pushedresult= re->result;
+ re->result= NULL;
+}
+
+/* if scemode is R_SINGLE_LAYER, at end of rendering, merge the both render results */
+void render_result_single_layer_end(Render *re)
+{
+ SceneRenderLayer *srl;
+ RenderLayer *rlpush;
+ RenderLayer *rl;
+ int nr;
+
+ if(re->result==NULL) {
+ printf("pop render result error; no current result!\n");
+ return;
+ }
+
+ if(!re->pushedresult)
+ return;
+
+ if(re->pushedresult->rectx==re->result->rectx && re->pushedresult->recty==re->result->recty) {
+ /* find which layer in re->pushedresult should be replaced */
+ rl= re->result->layers.first;
+
+ /* render result should be empty after this */
+ BLI_remlink(&re->result->layers, rl);
+
+ /* reconstruct render result layers */
+ for(nr=0, srl= re->scene->r.layers.first; srl; srl= srl->next, nr++) {
+ if(nr==re->r.actlay)
+ BLI_addtail(&re->result->layers, rl);
+ else {
+ rlpush= RE_GetRenderLayer(re->pushedresult, srl->name);
+ if(rlpush) {
+ BLI_remlink(&re->pushedresult->layers, rlpush);
+ BLI_addtail(&re->result->layers, rlpush);
+ }
+ }
+ }
+ }
+
+ RE_FreeRenderResult(re->pushedresult);
+ re->pushedresult= NULL;
+}
+
+/************************* EXR Tile File Rendering ***************************/
+
+static void save_render_result_tile(RenderResult *rr, RenderResult *rrpart)
+{
+ RenderLayer *rlp;
+ RenderPass *rpassp;
+ int offs, partx, party;
+
+ BLI_lock_thread(LOCK_IMAGE);
+
+ for(rlp= rrpart->layers.first; rlp; rlp= rlp->next) {
+
+ if(rrpart->crop) { /* filters add pixel extra */
+ offs= (rrpart->crop + rrpart->crop*rrpart->rectx);
+ }
+ else {
+ offs= 0;
+ }
+
+ /* combined */
+ if(rlp->rectf) {
+ int a, xstride= 4;
+ for(a=0; a<xstride; a++)
+ IMB_exr_set_channel(rr->exrhandle, rlp->name, get_pass_name(SCE_PASS_COMBINED, a),
+ xstride, xstride*rrpart->rectx, rlp->rectf+a + xstride*offs);
+ }
+
+ /* passes are allocated in sync */
+ for(rpassp= rlp->passes.first; rpassp; rpassp= rpassp->next) {
+ int a, xstride= rpassp->channels;
+ for(a=0; a<xstride; a++)
+ IMB_exr_set_channel(rr->exrhandle, rlp->name, get_pass_name(rpassp->passtype, a),
+ xstride, xstride*rrpart->rectx, rpassp->rect+a + xstride*offs);
+ }
+
+ }
+
+ party= rrpart->tilerect.ymin + rrpart->crop;
+ partx= rrpart->tilerect.xmin + rrpart->crop;
+ IMB_exrtile_write_channels(rr->exrhandle, partx, party, 0);
+
+ BLI_unlock_thread(LOCK_IMAGE);
+}
+
+static void save_empty_result_tiles(Render *re)
+{
+ RenderPart *pa;
+ RenderResult *rr;
+
+ for(rr= re->result; rr; rr= rr->next) {
+ IMB_exrtile_clear_channels(rr->exrhandle);
+
+ for(pa= re->parts.first; pa; pa= pa->next) {
+ if(pa->ready==0) {
+ int party= pa->disprect.ymin - re->disprect.ymin + pa->crop;
+ int partx= pa->disprect.xmin - re->disprect.xmin + pa->crop;
+ IMB_exrtile_write_channels(rr->exrhandle, partx, party, 0);
+ }
+ }
+ }
+}
+
+/* begin write of exr tile file */
+void render_result_exr_file_begin(Render *re)
+{
+ RenderResult *rr;
+ char str[FILE_MAX];
+
+ for(rr= re->result; rr; rr= rr->next) {
+ render_result_exr_file_path(re->scene, rr->sample_nr, str);
+
+ printf("write exr tmp file, %dx%d, %s\n", rr->rectx, rr->recty, str);
+ IMB_exrtile_begin_write(rr->exrhandle, str, 0, rr->rectx, rr->recty, re->partx, re->party);
+ }
+}
+
+/* end write of exr tile file, read back first sample */
+void render_result_exr_file_end(Render *re)
+{
+ RenderResult *rr;
+
+ save_empty_result_tiles(re);
+
+ for(rr= re->result; rr; rr= rr->next) {
+ IMB_exr_close(rr->exrhandle);
+ rr->exrhandle= NULL;
+ }
+
+ render_result_free_list(&re->fullresult, re->result);
+ re->result= NULL;
+
+ render_result_exr_file_read(re, 0);
+}
+
+/* save part into exr file */
+void render_result_exr_file_merge(RenderResult *rr, RenderResult *rrpart)
+{
+ for(; rr && rrpart; rr= rr->next, rrpart= rrpart->next)
+ save_render_result_tile(rr, rrpart);
+}
+
+/* path to temporary exr file */
+void render_result_exr_file_path(Scene *scene, int sample, char *filepath)
+{
+ char di[FILE_MAX], name[FILE_MAXFILE+MAX_ID_NAME+100], fi[FILE_MAXFILE];
+
+ BLI_strncpy(di, G.main->name, FILE_MAX);
+ BLI_splitdirstring(di, fi);
+
+ if(sample==0)
+ BLI_snprintf(name, sizeof(name), "%s_%s.exr", fi, scene->id.name+2);
+ else
+ BLI_snprintf(name, sizeof(name), "%s_%s%d.exr", fi, scene->id.name+2, sample);
+
+ BLI_make_file_string("/", filepath, BLI_temporary_dir(), name);
+}
+
+/* only for temp buffer files, makes exact copy of render result */
+int render_result_exr_file_read(Render *re, int sample)
+{
+ char str[FILE_MAX];
+ int success;
+
+ RE_FreeRenderResult(re->result);
+ re->result= render_result_new(re, &re->disprect, 0, RR_USE_MEM);
+
+ render_result_exr_file_path(re->scene, sample, str);
+ printf("read exr tmp file: %s\n", str);
+
+ if(render_result_exr_file_read_path(re->result, str)) {
+ success= TRUE;
+ }
+ else {
+ printf("cannot read: %s\n", str);
+ success= FALSE;
+
+ }
+
+ return success;
+}
+
+/* called for reading temp files, and for external engines */
+int render_result_exr_file_read_path(RenderResult *rr, const char *filepath)
+{
+ RenderLayer *rl;
+ RenderPass *rpass;
+ void *exrhandle= IMB_exr_get_handle();
+ int rectx, recty;
+
+ if(IMB_exr_begin_read(exrhandle, filepath, &rectx, &recty)==0) {
+ printf("failed being read %s\n", filepath);
+ IMB_exr_close(exrhandle);
+ return 0;
+ }
+
+ if(rr == NULL || rectx!=rr->rectx || recty!=rr->recty) {
+ if(rr)
+ printf("error in reading render result: dimensions don't match\n");
+ else
+ printf("error in reading render result: NULL result pointer\n");
+ IMB_exr_close(exrhandle);
+ return 0;
+ }
+
+ for(rl= rr->layers.first; rl; rl= rl->next) {
+ /* combined */
+ if(rl->rectf) {
+ int a, xstride= 4;
+ for(a=0; a<xstride; a++)
+ IMB_exr_set_channel(exrhandle, rl->name, get_pass_name(SCE_PASS_COMBINED, a),
+ xstride, xstride*rectx, rl->rectf+a);
+ }
+
+ /* passes are allocated in sync */
+ for(rpass= rl->passes.first; rpass; rpass= rpass->next) {
+ int a, xstride= rpass->channels;
+ for(a=0; a<xstride; a++)
+ IMB_exr_set_channel(exrhandle, rl->name, get_pass_name(rpass->passtype, a),
+ xstride, xstride*rectx, rpass->rect+a);
+
+ BLI_strncpy(rpass->name, get_pass_name(rpass->passtype, -1), sizeof(rpass->name));
+ }
+ }
+
+ IMB_exr_read_channels(exrhandle);
+ IMB_exr_close(exrhandle);
+
+ return 1;
+}
+
+/*************************** Combined Pixel Rect *****************************/
+
+ImBuf *render_result_rect_to_ibuf(RenderResult *rr, RenderData *rd)
+{
+ int flags = (rd->color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE)? IB_cm_predivide: 0;
+ ImBuf *ibuf= IMB_allocImBuf(rr->rectx, rr->recty, rd->im_format.planes, flags);
+
+ /* if not exists, BKE_write_ibuf makes one */
+ ibuf->rect= (unsigned int *)rr->rect32;
+ ibuf->rect_float= rr->rectf;
+ ibuf->zbuf_float= rr->rectz;
+
+ /* float factor for random dither, imbuf takes care of it */
+ ibuf->dither= rd->dither_intensity;
+
+ /* prepare to gamma correct to sRGB color space */
+ if (rd->color_mgt_flag & R_COLOR_MANAGEMENT) {
+ /* sequence editor can generate 8bpc render buffers */
+ if (ibuf->rect) {
+ ibuf->profile = IB_PROFILE_SRGB;
+ if (BKE_imtype_valid_depths(rd->im_format.imtype) & (R_IMF_CHAN_DEPTH_12|R_IMF_CHAN_DEPTH_16|R_IMF_CHAN_DEPTH_24|R_IMF_CHAN_DEPTH_32))
+ IMB_float_from_rect(ibuf);
+ } else {
+ ibuf->profile = IB_PROFILE_LINEAR_RGB;
+ }
+ }
+
+ /* color -> greyscale */
+ /* editing directly would alter the render view */
+ if(rd->im_format.planes == R_IMF_PLANES_BW) {
+ ImBuf *ibuf_bw= IMB_dupImBuf(ibuf);
+ IMB_color_to_bw(ibuf_bw);
+ IMB_freeImBuf(ibuf);
+ ibuf= ibuf_bw;
+ }
+
+ return ibuf;
+}
+
+void render_result_rect_from_ibuf(RenderResult *rr, RenderData *rd, ImBuf *ibuf)
+{
+ if(ibuf->rect_float) {
+ /* color management: when off ensure rectf is non-lin, since thats what the internal
+ * render engine delivers */
+ int profile_to= (rd->color_mgt_flag & R_COLOR_MANAGEMENT)? IB_PROFILE_LINEAR_RGB: IB_PROFILE_SRGB;
+ int profile_from= (ibuf->profile == IB_PROFILE_LINEAR_RGB)? IB_PROFILE_LINEAR_RGB: IB_PROFILE_SRGB;
+ int predivide= (rd->color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE);
+
+ if (!rr->rectf)
+ rr->rectf= MEM_mallocN(4*sizeof(float)*rr->rectx*rr->recty, "render_seq rectf");
+
+ IMB_buffer_float_from_float(rr->rectf, ibuf->rect_float,
+ 4, profile_to, profile_from, predivide,
+ rr->rectx, rr->recty, rr->rectx, rr->rectx);
+
+ /* TSK! Since sequence render doesn't free the *rr render result, the old rect32
+ can hang around when sequence render has rendered a 32 bits one before */
+ if(rr->rect32) {
+ MEM_freeN(rr->rect32);
+ rr->rect32= NULL;
+ }
+ }
+ else if(ibuf->rect) {
+ if (!rr->rect32)
+ rr->rect32= MEM_mallocN(sizeof(int)*rr->rectx*rr->recty, "render_seq rect");
+
+ memcpy(rr->rect32, ibuf->rect, 4*rr->rectx*rr->recty);
+
+ /* Same things as above, old rectf can hang around from previous render. */
+ if(rr->rectf) {
+ MEM_freeN(rr->rectf);
+ rr->rectf= NULL;
+ }
+ }
+}
+
+void render_result_rect_fill_zero(RenderResult *rr)
+{
+ if (rr->rectf)
+ memset(rr->rectf, 0, 4*sizeof(float)*rr->rectx*rr->recty);
+ else if (rr->rect32)
+ memset(rr->rect32, 0, 4*rr->rectx*rr->recty);
+ else
+ rr->rect32= MEM_callocN(sizeof(int)*rr->rectx*rr->recty, "render_seq rect");
+}
+
+void render_result_rect_get_pixels(RenderResult *rr, RenderData *rd, unsigned int *rect, int rectx, int recty)
+{
+ if(rr->rect32) {
+ memcpy(rect, rr->rect32, sizeof(int)*rr->rectx*rr->recty);
+ }
+ else if(rr->rectf) {
+ int profile_from= (rd->color_mgt_flag & R_COLOR_MANAGEMENT)? IB_PROFILE_LINEAR_RGB: IB_PROFILE_SRGB;
+ int predivide= (rd->color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE);
+ int dither= 0;
+
+ IMB_buffer_byte_from_float((unsigned char*)rect, rr->rectf,
+ 4, dither, IB_PROFILE_SRGB, profile_from, predivide,
+ rr->rectx, rr->recty, rr->rectx, rr->rectx);
+ }
+ else
+ /* else fill with black */
+ memset(rect, 0, sizeof(int)*rectx*recty);
+}
+
diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c
index f9992050052..5fba0bba48c 100644
--- a/source/blender/render/intern/source/render_texture.c
+++ b/source/blender/render/intern/source/render_texture.c
@@ -1969,7 +1969,10 @@ static int ntap_bump_compute(NTapBump *ntap_bump, ShadeInput *shi, MTex *mtex, T
{
auto_bump = shi->obr->ob->derivedFinal->auto_bump_scale;
}
- auto_bump /= sqrtf((float) (dimx*dimy));
+ {
+ float fVirtDim = sqrtf(fabsf((float) (dimx*dimy)*mtex->size[0]*mtex->size[1]));
+ auto_bump /= MAX2(fVirtDim, FLT_EPSILON);
+ }
// this variant using a derivative map is described here
// http://mmikkelsen3d.blogspot.com/2011/07/derivative-maps.html
diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c
index 96f9918891a..630acf3d88a 100644
--- a/source/blender/render/intern/source/rendercore.c
+++ b/source/blender/render/intern/source/rendercore.c
@@ -67,6 +67,7 @@
#include "rayintersection.h"
#include "rayobject.h"
#include "renderpipeline.h"
+#include "render_result.h"
#include "render_types.h"
#include "renderdatabase.h"
#include "occlusion.h"
diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c
index 8efe23c38f9..c77a1309743 100644
--- a/source/blender/render/intern/source/zbuf.c
+++ b/source/blender/render/intern/source/zbuf.c
@@ -63,6 +63,7 @@
/* local includes */
#include "gammaCorrectionTables.h"
#include "pixelblending.h"
+#include "render_result.h"
#include "render_types.h"
#include "renderpipeline.h"
#include "renderdatabase.h"
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index 43a691770c9..43ed2b3b2b9 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -225,20 +225,8 @@ void wm_event_do_notifiers(bContext *C)
if(note->window==win || (note->window == NULL && (note->reference == NULL || note->reference == CTX_data_scene(C)))) {
if(note->category==NC_SCENE) {
- if(note->data==ND_SCENEBROWSE) {
- ED_screen_set_scene(C, note->reference); // XXX hrms, think this over!
- if(G.f & G_DEBUG)
- printf("scene set %p\n", note->reference);
- }
- else if(note->data==ND_FRAME)
+ if(note->data==ND_FRAME)
do_anim= 1;
-
- if(note->action == NA_REMOVED) {
- ED_screen_delete_scene(C, note->reference); // XXX hrms, think this over!
- if(G.f & G_DEBUG)
- printf("scene delete %p\n", note->reference);
- }
-
}
}
if(ELEM5(note->category, NC_SCENE, NC_OBJECT, NC_GEOM, NC_SCENE, NC_WM)) {
diff --git a/source/creator/creator.c b/source/creator/creator.c
index 70624a692bf..ee4f5c068a8 100644
--- a/source/creator/creator.c
+++ b/source/creator/creator.c
@@ -927,6 +927,12 @@ static int load_file(int UNUSED(argc), const char **argv, void *data)
/* Make the path absolute because its needed for relative linked blends to be found */
char filename[FILE_MAX];
+
+ /* note, we could skip these, but so far we always tried to load these files */
+ if (argv[0][0] == '-') {
+ fprintf(stderr, "unknown argument, loading as file: %s\n", argv[0]);
+ }
+
BLI_strncpy(filename, argv[0], sizeof(filename));
BLI_path_cwd(filename);
diff --git a/source/gameengine/Converter/KX_ConvertProperties.cpp b/source/gameengine/Converter/KX_ConvertProperties.cpp
index 7a574276eb4..8eea39c4956 100644
--- a/source/gameengine/Converter/KX_ConvertProperties.cpp
+++ b/source/gameengine/Converter/KX_ConvertProperties.cpp
@@ -48,11 +48,21 @@
#include "SCA_TimeEventManager.h"
#include "SCA_IScene.h"
+#include "KX_FontObject.h"
+#include "DNA_curve_types.h"
+
/* This little block needed for linking to Blender... */
#ifdef WIN32
#include "BLI_winstuff.h"
#endif
+extern "C" {
+ #include "BKE_property.h"
+}
+
+/* prototype */
+void BL_ConvertTextProperty(Object* object, KX_FontObject* fontobj,SCA_TimeEventManager* timemgr,SCA_IScene* scene, bool isInActiveLayer);
+
void BL_ConvertProperties(Object* object,KX_GameObject* gameobj,SCA_TimeEventManager* timemgr,SCA_IScene* scene, bool isInActiveLayer)
{
@@ -155,4 +165,80 @@ void BL_ConvertProperties(Object* object,KX_GameObject* gameobj,SCA_TimeEventMan
// reserve name for object state
scene->AddDebugProperty(gameobj,STR_String("__state__"));
}
+
+ /* Font Objects need to 'copy' the Font Object data body to ["Text"] */
+ if (object->type == OB_FONT)
+ {
+ BL_ConvertTextProperty(object, (KX_FontObject *)gameobj, timemgr, scene, isInActiveLayer);
+ }
+}
+
+void BL_ConvertTextProperty(Object* object, KX_FontObject* fontobj,SCA_TimeEventManager* timemgr,SCA_IScene* scene, bool isInActiveLayer)
+{
+ CValue* tprop = fontobj->GetProperty("Text");
+ if(!tprop) return;
+ bProperty* prop = get_ob_property(object, "Text");
+ if(!prop) return;
+
+ Curve *curve = static_cast<Curve *>(object->data);
+ STR_String str = curve->str;
+ CValue* propval = NULL;
+
+ switch(prop->type) {
+ case GPROP_BOOL:
+ {
+ int value = atoi(str);
+ propval = new CBoolValue((bool)(value != 0));
+ tprop->SetValue(propval);
+ break;
+ }
+ case GPROP_INT:
+ {
+ int value = atoi(str);
+ propval = new CIntValue(value);
+ tprop->SetValue(propval);
+ break;
+ }
+ case GPROP_FLOAT:
+ {
+ float floatprop = atof(str);
+ propval = new CFloatValue(floatprop);
+ tprop->SetValue(propval);
+ break;
+ }
+ case GPROP_STRING:
+ {
+ propval = new CStringValue(str, "");
+ tprop->SetValue(propval);
+ break;
+ }
+ case GPROP_TIME:
+ {
+ float floatprop = atof(str);
+
+ CValue* timeval = new CFloatValue(floatprop);
+ // set a subproperty called 'timer' so that
+ // we can register the replica of this property
+ // at the time a game object is replicated (AddObjectActuator triggers this)
+ CValue *bval = new CBoolValue(true);
+ timeval->SetProperty("timer",bval);
+ bval->Release();
+ if (isInActiveLayer)
+ {
+ timemgr->AddTimeProperty(timeval);
+ }
+
+ propval = timeval;
+ tprop->SetValue(timeval);
+ }
+ default:
+ {
+ // todo make an assert etc.
+ }
+ }
+
+ if (propval) {
+ propval->Release();
+ }
}
+
diff --git a/source/gameengine/GameLogic/CMakeLists.txt b/source/gameengine/GameLogic/CMakeLists.txt
index 64c2af9031b..98255bb8b97 100644
--- a/source/gameengine/GameLogic/CMakeLists.txt
+++ b/source/gameengine/GameLogic/CMakeLists.txt
@@ -132,6 +132,10 @@ if(WITH_SDL)
)
add_definitions(-DWITH_SDL)
+
+ if(WITH_GHOST_SDL)
+ add_definitions(-DWITH_GHOST_SDL)
+ endif()
endif()
blender_add_lib(ge_logic "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp b/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp
index 0547d97285d..15aeef242b7 100644
--- a/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp
+++ b/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp
@@ -88,8 +88,14 @@ SCA_Joystick *SCA_Joystick::GetInstance( short int joyindex )
if (m_refCount == 0)
{
int i;
- // do this once only
+ // The video subsystem is required for joystick input to work. However,
+ // when GHOST is running under SDL, video is initialised elsewhere.
+ // Do this once only.
+# ifdef WITH_GHOST_SDL
+ if(SDL_InitSubSystem(SDL_INIT_JOYSTICK) == -1 ){
+# else
if(SDL_InitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_VIDEO) == -1 ){
+# endif
echo("Error-Initializing-SDL: " << SDL_GetError());
return NULL;
}
@@ -124,7 +130,14 @@ void SCA_Joystick::ReleaseInstance()
m_instance[i]= NULL;
}
+ // The video subsystem is required for joystick input to work. However,
+ // when GHOST is running under SDL, video is freed elsewhere.
+ // Do this once only.
+# ifdef WITH_GHOST_SDL
+ SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
+# else
SDL_QuitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_VIDEO);
+# endif
#endif /* WITH_SDL */
}
}
diff --git a/source/gameengine/Ketsji/KX_FontObject.cpp b/source/gameengine/Ketsji/KX_FontObject.cpp
index 5a4d9065605..8cce9471587 100644
--- a/source/gameengine/Ketsji/KX_FontObject.cpp
+++ b/source/gameengine/Ketsji/KX_FontObject.cpp
@@ -34,6 +34,14 @@
#include "KX_Scene.h"
#include "KX_PythonInit.h"
#include "BLI_math.h"
+#include "StringValue.h"
+
+/* paths needed for font load */
+#include "BLI_blenlib.h"
+#include "BKE_global.h"
+#include "BKE_font.h"
+#include "BKE_main.h"
+#include "DNA_packedFile_types.h"
extern "C" {
#include "BLF_api.h"
@@ -41,6 +49,9 @@ extern "C" {
#define BGE_FONT_RES 100
+/* proptotype */
+int GetFontId(VFont *font);
+
std::vector<STR_String> split_string(STR_String str)
{
std::vector<STR_String> text = std::vector<STR_String>();
@@ -61,6 +72,7 @@ std::vector<STR_String> split_string(STR_String str)
return text;
}
+
KX_FontObject::KX_FontObject( void* sgReplicationInfo,
SG_Callbacks callbacks,
RAS_IRenderTools* rendertools,
@@ -76,20 +88,9 @@ KX_FontObject::KX_FontObject( void* sgReplicationInfo,
m_fsize = text->fsize;
m_line_spacing = text->linedist;
m_offset = MT_Vector3(text->xof, text->yof, 0);
-
- /* FO_BUILTIN_NAME != "default" */
- /* I hope at some point Blender (2.5x) can have a single font */
- /* with unicode support for ui and OB_FONT */
- /* once we have packed working we can load the FO_BUILTIN_NAME font */
- const char* filepath = text->vfont->name;
- if (strcmp(FO_BUILTIN_NAME, filepath) == 0)
- filepath = "default";
-
- /* XXX - if it's packed it will not work. waiting for bdiego (Diego) fix for that. */
- m_fontid = BLF_load(filepath);
- if (m_fontid == -1)
- m_fontid = BLF_load("default");
-
+
+ m_fontid = GetFontId(text->vfont);
+
/* initialize the color with the object color and store it in the KX_Object class
This is a workaround waiting for the fix:
[#25487] BGE: Object Color only works when it has a keyed frame */
@@ -115,6 +116,50 @@ void KX_FontObject::ProcessReplica()
KX_GetActiveScene()->AddFont(this);
}
+int GetFontId (VFont *font) {
+ PackedFile *packedfile=NULL;
+ int fontid = -1;
+
+ if (font->packedfile) {
+ packedfile= font->packedfile;
+ fontid= BLF_load_mem(font->name, (unsigned char*)packedfile->data, packedfile->size);
+
+ if (fontid == -1) {
+ printf("ERROR: packed font \"%s\" could not be loaded.\n", font->name);
+ fontid = BLF_load("default");
+ }
+ return fontid;
+ }
+
+ /* once we have packed working we can load the FO_BUILTIN_NAME font */
+ const char *filepath = font->name;
+ if (strcmp(FO_BUILTIN_NAME, filepath) == 0) {
+ fontid = BLF_load("default");
+
+ /* XXX the following code is supposed to work (after you add get_builtin_packedfile to BKE_font.h )
+ * unfortunately it's crashing on blf_glyph.c:173 because gc->max_glyph_width is 0
+ */
+ // packedfile=get_builtin_packedfile();
+ // fontid= BLF_load_mem(font->name, (unsigned char*)packedfile->data, packedfile->size);
+ // return fontid;
+
+ return BLF_load("default");
+ }
+
+ /* convert from absolute to relative */
+ char expanded[256]; // font names can be bigger than FILE_MAX (240)
+ BLI_strncpy(expanded, filepath, 256);
+ BLI_path_abs(expanded, G.main->name);
+
+ fontid = BLF_load(expanded);
+
+ /* fallback */
+ if (fontid == -1)
+ fontid = BLF_load("default");
+
+ return fontid;
+}
+
void KX_FontObject::DrawText()
{
/* Allow for some logic brick control */
@@ -224,7 +269,18 @@ int KX_FontObject::pyattr_set_text(void *self_v, const KX_PYATTRIBUTE_DEF *attrd
if(!PyUnicode_Check(value))
return PY_SET_ATTR_FAIL;
char* chars = _PyUnicode_AsString(value);
- self->m_text = split_string(STR_String(chars));
+
+ /* Allow for some logic brick control */
+ CValue* tprop = self->GetProperty("Text");
+ if(tprop) {
+ CValue *newstringprop = new CStringValue(STR_String(chars), "Text");
+ self->SetProperty("Text", newstringprop);
+ newstringprop->Release();
+ }
+ else {
+ self->m_text = split_string(STR_String(chars));
+ }
+
return PY_SET_ATTR_SUCCESS;
}