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:
-rw-r--r--CMakeLists.txt42
-rw-r--r--GNUmakefile18
-rw-r--r--SConstruct9
-rw-r--r--build_files/cmake/FindPythonLibsUnix.cmake37
-rwxr-xr-xbuild_files/cmake/cmake_consistency_check.py25
-rwxr-xr-xbuild_files/cmake/example_scripts/cmake_linux_install.sh2
-rw-r--r--build_files/cmake/macros.cmake62
-rw-r--r--build_files/scons/config/win32-vc-config.py4
-rw-r--r--build_files/scons/config/win64-vc-config.py2
-rw-r--r--build_files/scons/tools/Blender.py59
-rw-r--r--doc/manpage/blender.121
-rw-r--r--doc/python_api/rst/bge.logic.rst6
-rw-r--r--doc/python_api/rst/bge.types.rst6
-rw-r--r--intern/elbeem/extern/elbeem.h8
-rw-r--r--intern/elbeem/intern/simulation_object.cpp3
-rw-r--r--intern/elbeem/intern/solver_class.h3
-rw-r--r--intern/elbeem/intern/solver_init.cpp9
-rw-r--r--intern/elbeem/intern/solver_interface.h3
-rw-r--r--intern/ghost/CMakeLists.txt37
-rw-r--r--intern/ghost/intern/GHOST_DisplayManagerNULL.h51
-rw-r--r--intern/ghost/intern/GHOST_ISystem.cpp8
-rw-r--r--intern/ghost/intern/GHOST_NDOFManager.cpp4
-rw-r--r--intern/ghost/intern/GHOST_SystemNULL.h93
-rw-r--r--intern/ghost/intern/GHOST_WindowNULL.h96
-rw-r--r--release/scripts/modules/console/complete_namespace.py7
-rw-r--r--release/scripts/modules/console/intellisense.py14
-rw-r--r--release/scripts/modules/console_python.py2
-rw-r--r--release/scripts/startup/bl_operators/object_quick_effects.py170
-rw-r--r--release/scripts/startup/bl_operators/presets.py2
-rw-r--r--release/scripts/startup/bl_operators/wm.py29
-rw-r--r--release/scripts/startup/bl_ui/properties_data_curve.py4
-rw-r--r--release/scripts/startup/bl_ui/properties_data_mesh.py12
-rw-r--r--release/scripts/startup/bl_ui/properties_data_metaball.py4
-rw-r--r--release/scripts/startup/bl_ui/properties_data_modifier.py8
-rw-r--r--release/scripts/startup/bl_ui/properties_object_constraint.py8
-rw-r--r--release/scripts/startup/bl_ui/properties_physics_fluid.py1
-rw-r--r--release/scripts/startup/bl_ui/properties_render.py385
-rw-r--r--release/scripts/startup/bl_ui/space_sequencer.py26
-rw-r--r--release/scripts/startup/bl_ui/space_text.py2
-rw-r--r--release/scripts/startup/bl_ui/space_userpref.py13
-rw-r--r--release/scripts/startup/bl_ui/space_view3d.py6
-rw-r--r--source/blender/blenkernel/BKE_blender.h1
-rw-r--r--source/blender/blenkernel/BKE_brush.h4
-rw-r--r--source/blender/blenkernel/BKE_deform.h4
-rw-r--r--source/blender/blenkernel/BKE_depsgraph.h19
-rw-r--r--source/blender/blenkernel/BKE_multires.h1
-rw-r--r--source/blender/blenkernel/BKE_particle.h2
-rw-r--r--source/blender/blenkernel/intern/blender.c18
-rw-r--r--source/blender/blenkernel/intern/brush.c33
-rw-r--r--source/blender/blenkernel/intern/bvhutils.c2
-rw-r--r--source/blender/blenkernel/intern/customdata.c2
-rw-r--r--source/blender/blenkernel/intern/deform.c4
-rw-r--r--source/blender/blenkernel/intern/multires.c60
-rw-r--r--source/blender/blenkernel/intern/object.c73
-rw-r--r--source/blender/blenkernel/intern/particle_system.c114
-rw-r--r--source/blender/blenkernel/intern/sca.c1
-rw-r--r--source/blender/blenkernel/intern/scene.c3
-rw-r--r--source/blender/blenkernel/intern/seqeffects.c11
-rw-r--r--source/blender/blenkernel/intern/sequencer.c16
-rw-r--r--source/blender/blenlib/BLI_math_geom.h3
-rw-r--r--source/blender/blenlib/BLI_math_vector.h2
-rw-r--r--source/blender/blenlib/BLI_utildefines.h6
-rw-r--r--source/blender/blenlib/intern/math_base_inline.c2
-rw-r--r--source/blender/blenlib/intern/math_geom.c74
-rw-r--r--source/blender/blenlib/intern/math_vector_inline.c15
-rw-r--r--source/blender/blenlib/intern/path_util.c6
-rw-r--r--source/blender/blenloader/intern/readfile.c52
-rw-r--r--source/blender/collada/DocumentImporter.cpp14
-rw-r--r--source/blender/collada/EffectExporter.cpp2
-rw-r--r--source/blender/collada/LightExporter.cpp6
-rw-r--r--source/blender/editors/animation/anim_channels_edit.c1
-rw-r--r--source/blender/editors/animation/anim_markers.c7
-rw-r--r--source/blender/editors/animation/anim_ops.c5
-rw-r--r--source/blender/editors/datafiles/CMakeLists.txt71
-rw-r--r--source/blender/editors/datafiles/startup.blend.c4
-rw-r--r--source/blender/editors/include/ED_mesh.h4
-rw-r--r--source/blender/editors/include/ED_particle.h3
-rw-r--r--source/blender/editors/include/ED_screen.h3
-rw-r--r--source/blender/editors/include/ED_types.h4
-rw-r--r--source/blender/editors/include/ED_util.h5
-rw-r--r--source/blender/editors/include/ED_view3d.h1
-rw-r--r--source/blender/editors/include/UI_interface.h9
-rw-r--r--source/blender/editors/include/UI_interface_icons.h4
-rw-r--r--source/blender/editors/interface/CMakeLists.txt4
-rw-r--r--source/blender/editors/interface/interface.c87
-rw-r--r--source/blender/editors/interface/interface_draw.c27
-rw-r--r--source/blender/editors/interface/interface_handlers.c90
-rw-r--r--source/blender/editors/interface/interface_icons.c14
-rw-r--r--source/blender/editors/interface/interface_intern.h22
-rw-r--r--source/blender/editors/interface/interface_layout.c3
-rw-r--r--source/blender/editors/interface/interface_panel.c11
-rw-r--r--source/blender/editors/interface/interface_regions.c102
-rw-r--r--source/blender/editors/interface/interface_templates.c37
-rw-r--r--source/blender/editors/interface/interface_widgets.c113
-rw-r--r--source/blender/editors/interface/resources.c6
-rw-r--r--source/blender/editors/interface/view2d_ops.c20
-rw-r--r--source/blender/editors/mesh/editmesh_loop.c1
-rw-r--r--source/blender/editors/mesh/editmesh_mods.c2
-rw-r--r--source/blender/editors/mesh/editmesh_tools.c2
-rw-r--r--source/blender/editors/object/object_add.c28
-rw-r--r--source/blender/editors/object/object_bake.c1270
-rw-r--r--source/blender/editors/object/object_modifier.c35
-rw-r--r--source/blender/editors/object/object_shapekey.c47
-rw-r--r--source/blender/editors/object/object_vgroup.c167
-rw-r--r--source/blender/editors/physics/particle_edit.c58
-rw-r--r--source/blender/editors/physics/physics_fluid.c53
-rw-r--r--source/blender/editors/render/render_internal.c3
-rw-r--r--source/blender/editors/render/render_view.c3
-rw-r--r--source/blender/editors/screen/area.c59
-rw-r--r--source/blender/editors/screen/screen_edit.c23
-rw-r--r--source/blender/editors/screen/screen_ops.c60
-rw-r--r--source/blender/editors/sculpt_paint/paint_image.c74
-rw-r--r--source/blender/editors/sculpt_paint/paint_intern.h1
-rw-r--r--source/blender/editors/sculpt_paint/paint_stroke.c13
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex.c16
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c19
-rw-r--r--source/blender/editors/space_action/action_select.c1
-rw-r--r--source/blender/editors/space_action/space_action.c1
-rw-r--r--source/blender/editors/space_api/spacetypes.c3
-rw-r--r--source/blender/editors/space_buttons/buttons_header.c6
-rw-r--r--source/blender/editors/space_console/console_draw.c2
-rw-r--r--source/blender/editors/space_file/CMakeLists.txt4
-rw-r--r--source/blender/editors/space_file/file_draw.c10
-rw-r--r--source/blender/editors/space_file/file_intern.h8
-rw-r--r--source/blender/editors/space_file/file_ops.c1
-rw-r--r--source/blender/editors/space_file/filelist.c4
-rw-r--r--source/blender/editors/space_file/filesel.c6
-rw-r--r--source/blender/editors/space_graph/graph_select.c1
-rw-r--r--source/blender/editors/space_image/image_buttons.c32
-rw-r--r--source/blender/editors/space_image/image_ops.c1
-rw-r--r--source/blender/editors/space_info/info_report.c1
-rw-r--r--source/blender/editors/space_logic/logic_buttons.c1
-rw-r--r--source/blender/editors/space_logic/logic_window.c2
-rw-r--r--source/blender/editors/space_nla/nla_select.c1
-rw-r--r--source/blender/editors/space_node/node_edit.c44
-rw-r--r--source/blender/editors/space_node/node_select.c1
-rw-r--r--source/blender/editors/space_outliner/outliner.c219
-rw-r--r--source/blender/editors/space_script/script_header.c6
-rw-r--r--source/blender/editors/space_sequencer/sequencer_draw.c8
-rw-r--r--source/blender/editors/space_sequencer/sequencer_edit.c3
-rw-r--r--source/blender/editors/space_sequencer/sequencer_select.c1
-rw-r--r--source/blender/editors/space_sound/sound_header.c6
-rw-r--r--source/blender/editors/space_view3d/drawobject.c2
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c11
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c34
-rw-r--r--source/blender/editors/space_view3d/view3d_header.c20
-rw-r--r--source/blender/editors/space_view3d/view3d_select.c32
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c6
-rw-r--r--source/blender/editors/transform/transform.c11
-rw-r--r--source/blender/editors/transform/transform_conversions.c40
-rw-r--r--source/blender/editors/transform/transform_generics.c3
-rw-r--r--source/blender/editors/util/ed_util.c25
-rw-r--r--source/blender/editors/util/editmode_undo.c66
-rw-r--r--source/blender/editors/util/undo.c178
-rw-r--r--source/blender/editors/util/util_intern.h8
-rw-r--r--source/blender/editors/uvedit/uvedit_ops.c2
-rw-r--r--source/blender/gpu/intern/gpu_draw.c22
-rw-r--r--source/blender/imbuf/IMB_imbuf.h12
-rw-r--r--source/blender/imbuf/intern/divers.c129
-rw-r--r--source/blender/imbuf/intern/filter.c64
-rw-r--r--source/blender/imbuf/intern/targa.c2
-rw-r--r--source/blender/makesdna/DNA_actuator_types.h2
-rw-r--r--source/blender/makesdna/DNA_lattice_types.h2
-rw-r--r--source/blender/makesdna/DNA_object_fluidsim.h5
-rw-r--r--source/blender/makesdna/DNA_scene_types.h22
-rw-r--r--source/blender/makesdna/DNA_screen_types.h1
-rw-r--r--source/blender/makesdna/DNA_sequence_types.h45
-rw-r--r--source/blender/makesdna/DNA_userdef_types.h5
-rw-r--r--source/blender/makesrna/RNA_access.h1
-rw-r--r--source/blender/makesrna/RNA_define.h3
-rw-r--r--source/blender/makesrna/RNA_types.h3
-rw-r--r--source/blender/makesrna/intern/rna_access.c14
-rw-r--r--source/blender/makesrna/intern/rna_actuator.c7
-rw-r--r--source/blender/makesrna/intern/rna_camera.c2
-rw-r--r--source/blender/makesrna/intern/rna_controller.c15
-rw-r--r--source/blender/makesrna/intern/rna_define.c11
-rw-r--r--source/blender/makesrna/intern/rna_fluidsim.c8
-rw-r--r--source/blender/makesrna/intern/rna_group.c2
-rw-r--r--source/blender/makesrna/intern/rna_internal_types.h5
-rw-r--r--source/blender/makesrna/intern/rna_mesh.c23
-rw-r--r--source/blender/makesrna/intern/rna_modifier.c43
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c2
-rw-r--r--source/blender/makesrna/intern/rna_object.c9
-rw-r--r--source/blender/makesrna/intern/rna_rna.c12
-rw-r--r--source/blender/makesrna/intern/rna_scene.c8
-rw-r--r--source/blender/makesrna/intern/rna_sequencer.c25
-rw-r--r--source/blender/makesrna/intern/rna_texture.c1
-rw-r--r--source/blender/makesrna/intern/rna_userdef.c16
-rw-r--r--source/blender/makesrna/intern/rna_wm.c8
-rw-r--r--source/blender/modifiers/CMakeLists.txt8
-rw-r--r--source/blender/modifiers/intern/MOD_cloth.c15
-rw-r--r--source/blender/modifiers/intern/MOD_explode.c24
-rw-r--r--source/blender/modifiers/intern/MOD_fluidsim_util.c10
-rw-r--r--source/blender/modifiers/intern/MOD_mask.c92
-rw-r--r--source/blender/modifiers/intern/MOD_meshdeform.c2
-rw-r--r--source/blender/modifiers/intern/MOD_none.c2
-rw-r--r--source/blender/modifiers/intern/MOD_smoke.c5
-rw-r--r--source/blender/nodes/intern/CMP_nodes/CMP_math.c7
-rw-r--r--source/blender/nodes/intern/CMP_util.c6
-rw-r--r--source/blender/nodes/intern/SHD_nodes/SHD_material.c25
-rw-r--r--source/blender/python/intern/bpy_driver.c5
-rw-r--r--source/blender/python/intern/bpy_props.c347
-rw-r--r--source/blender/python/intern/bpy_rna.c9
-rw-r--r--source/blender/python/intern/bpy_rna.h1
-rw-r--r--source/blender/render/extern/include/RE_pipeline.h2
-rw-r--r--source/blender/render/intern/include/render_types.h2
-rw-r--r--source/blender/render/intern/source/convertblender.c1
-rw-r--r--source/blender/render/intern/source/envmap.c1
-rw-r--r--source/blender/render/intern/source/imagetexture.c13
-rw-r--r--source/blender/render/intern/source/pipeline.c135
-rw-r--r--source/blender/render/intern/source/pixelshading.c25
-rw-r--r--source/blender/render/intern/source/render_texture.c4
-rw-r--r--source/blender/render/intern/source/rendercore.c80
-rw-r--r--source/blender/render/intern/source/shadeinput.c10
-rw-r--r--source/blender/render/intern/source/sunsky.c2
-rw-r--r--source/blender/render/intern/source/volumetric.c2
-rw-r--r--source/blender/windowmanager/CMakeLists.txt5
-rw-r--r--source/blender/windowmanager/WM_api.h5
-rw-r--r--source/blender/windowmanager/WM_types.h4
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c25
-rw-r--r--source/blender/windowmanager/intern/wm_files.c12
-rw-r--r--source/blender/windowmanager/intern/wm_init_exit.c9
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c132
-rw-r--r--source/blender/windowmanager/intern/wm_window.c6
-rw-r--r--source/blenderplayer/CMakeLists.txt6
-rw-r--r--source/blenderplayer/bad_level_call_stubs/CMakeLists.txt4
-rw-r--r--source/creator/CMakeLists.txt10
-rw-r--r--source/creator/SConscript47
-rw-r--r--source/creator/creator.c4
-rw-r--r--source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp2
-rw-r--r--source/gameengine/Converter/KX_ConvertActuators.cpp6
-rw-r--r--source/gameengine/GameLogic/SCA_2DFilterActuator.cpp6
-rw-r--r--source/gameengine/GameLogic/SCA_2DFilterActuator.h1
-rw-r--r--source/gameengine/Ketsji/KX_CameraActuator.cpp9
-rw-r--r--source/gameengine/Ketsji/KX_CameraActuator.h6
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsController.h58
-rw-r--r--source/tests/CMakeLists.txt36
-rw-r--r--source/tests/bl_load_py_modules.py11
238 files changed, 5248 insertions, 1773 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index dae8a37e572..2c27076c10e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -98,6 +98,10 @@ option(WITH_FFTW3 "Enable FFTW3 support (Used for smoke and audio effect
option(WITH_BULLET "Enable Bullet (Physics Engine)" ON)
option(WITH_GAMEENGINE "Enable Game Engine" ON)
option(WITH_PLAYER "Build Player" OFF)
+
+option(WITH_HEADLESS "Build without graphical support (renderfarm, server mode only)" OFF)
+mark_as_advanced(WITH_HEADLESS)
+
# (unix defaults to OpenMP On)
if(UNIX AND NOT APPLE)
option(WITH_OPENMP "Enable OpenMP (has to be supported by the compiler)" ON)
@@ -184,6 +188,9 @@ if(APPLE)
option(WITH_LIBS10.5 "Use 10.5 libs (needed for 64bit builds)" OFF)
endif()
+#-----------------------------------------------------------------------------
+# Check for conflicting/unsupported configurations
+
if(NOT WITH_GAMEENGINE AND WITH_PLAYER)
message(FATAL_ERROR "WITH_PLAYER requires WITH_GAMEENGINE")
endif()
@@ -205,8 +212,16 @@ if(WITH_PYTHON_MODULE AND WITH_PYTHON_INSTALL)
message(FATAL_ERROR "WITH_PYTHON_MODULE requires WITH_PYTHON_INSTALL to be OFF")
endif()
-# remove old vars
-unset(WITH_INSTALL CACHE)
+if(WITH_CODEC_QUICKTIME AND MINGW)
+ message(FATAL_ERROR "MINGW requires WITH_CODEC_QUICKTIME to be OFF "
+ "because it is currently unsupported, remove this "
+ "line if youre a developer who wants to add support.")
+endif()
+
+# may as well build python module without a UI
+if(WITH_PYTHON_MODULE)
+ set(WITH_HEADLESS ON)
+endif()
TEST_SSE_SUPPORT()
@@ -216,6 +231,9 @@ TEST_SSE_SUPPORT()
# linux only, not cached
set(WITH_BINRELOC OFF)
+# MAXOSX only, set to avoid uninitialized
+set(EXETYPE "")
+
# these are added to later on.
set(C_WARNINGS "")
set(CXX_WARNINGS "")
@@ -409,15 +427,19 @@ if(UNIX AND NOT APPLE)
unset(JEMALLOC)
endif()
- find_package(X11 REQUIRED)
- find_path(X11_XF86keysym_INCLUDE_PATH X11/XF86keysym.h ${X11_INC_SEARCH_PATH})
- mark_as_advanced(X11_XF86keysym_INCLUDE_PATH)
-
# OpenSuse needs lutil, ArchLinux not, for now keep, can avoid by using --as-needed
- set(LLIBS "-lutil -lc -lm -lpthread -lstdc++ ${X11_X11_LIB}")
+ set(LLIBS "-lutil -lc -lm -lpthread -lstdc++")
- if(WITH_X11_XINPUT)
- list(APPEND LLIBS ${X11_Xinput_LIB})
+ if(NOT WITH_HEADLESS)
+ find_package(X11 REQUIRED)
+ find_path(X11_XF86keysym_INCLUDE_PATH X11/XF86keysym.h ${X11_INC_SEARCH_PATH})
+ mark_as_advanced(X11_XF86keysym_INCLUDE_PATH)
+
+ list(APPEND LLIBS ${X11_X11_LIB})
+
+ if(WITH_X11_XINPUT)
+ list(APPEND LLIBS ${X11_Xinput_LIB})
+ endif()
endif()
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
@@ -1019,7 +1041,7 @@ endif()
#-----------------------------------------------------------------------------
# Configure OpenGL.
find_package(OpenGL)
-blender_include_dirs("${OPENGL_INCLUDE_DIR}")
+blender_include_dirs_sys("${OPENGL_INCLUDE_DIR}")
# unset(OPENGL_LIBRARIES CACHE) # not compat with older cmake
# unset(OPENGL_xmesa_INCLUDE_DIR CACHE) # not compat with older cmake
diff --git a/GNUmakefile b/GNUmakefile
index 008dfe77eae..47073bf5734 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -64,21 +64,19 @@ endif
# Build Blender
all:
- @echo
+ @echo
@echo Configuring Blender ...
if test ! -f $(BUILD_DIR)/CMakeCache.txt ; then \
- mkdir -p $(BUILD_DIR) ; \
- cd $(BUILD_DIR) ; \
- cmake $(BLENDER_DIR) -DCMAKE_BUILD_TYPE:STRING=$(BUILD_TYPE) ; \
+ cmake -H$(BLENDER_DIR) -B$(BUILD_DIR) -DCMAKE_BUILD_TYPE:STRING=$(BUILD_TYPE) ; \
fi
- @echo
+ @echo
@echo Building Blender ...
- cd $(BUILD_DIR) ; make -s -j $(NPROCS) install
- @echo
+ make -C $(BUILD_DIR) -s -j $(NPROCS) install
+ @echo
@echo run blender from "$(BUILD_DIR)/bin/blender"
- @echo
+ @echo
debug: all
# pass
@@ -91,7 +89,7 @@ package_pacman:
cd build_files/package_spec/pacman ; MAKEFLAGS="-j$(NPROCS)" makepkg --asroot
package_archive:
- cd $(BUILD_DIR) ; make -s package_archive
+ make -C $(BUILD_DIR) -s package_archive
@echo archive in "$(BUILD_DIR)/release"
# forward build targets
@@ -109,6 +107,6 @@ test_cmake:
@echo "written: test_cmake_consistency.log"
clean:
- cd $(BUILD_DIR) ; make clean
+ make -C $(BUILD_DIR) clean
.PHONY: all
diff --git a/SConstruct b/SConstruct
index e928970f6b8..2f63ddf0501 100644
--- a/SConstruct
+++ b/SConstruct
@@ -306,10 +306,6 @@ if env['BF_NO_ELBEEM'] == 1:
env['CXXFLAGS'].append('-DDISABLE_ELBEEM')
env['CCFLAGS'].append('-DDISABLE_ELBEEM')
-if env['WITH_BF_SDL'] == False and env['OURPLATFORM'] in ('win32-vc', 'win32-ming', 'win64-vc'):
- env['PLATFORM_LINKFLAGS'].remove('/ENTRY:mainCRTStartup')
- env['PLATFORM_LINKFLAGS'].append('/ENTRY:main')
-
# lastly we check for root_build_dir ( we should not do before, otherwise we might do wrong builddir
B.root_build_dir = env['BF_BUILDDIR']
B.doc_build_dir = os.path.join(env['BF_INSTALLDIR'], 'doc')
@@ -409,17 +405,18 @@ if B.arguments.get('BF_PRIORITYLIST', '0')=='1':
B.propose_priorities()
dobj = B.buildinfo(env, "dynamic") + B.resources
+creob = B.creator(env)
thestatlibs, thelibincs = B.setup_staticlibs(env)
thesyslibs = B.setup_syslibs(env)
if 'blender' in B.targets or not env['WITH_BF_NOBLENDER']:
- env.BlenderProg(B.root_build_dir, "blender", mainlist + thestatlibs + dobj, thesyslibs, [B.root_build_dir+'/lib'] + thelibincs, 'blender')
+ env.BlenderProg(B.root_build_dir, "blender", creob + mainlist + thestatlibs + dobj, thesyslibs, [B.root_build_dir+'/lib'] + thelibincs, 'blender')
if env['WITH_BF_PLAYER']:
playerlist = B.create_blender_liblist(env, 'player')
playerlist += B.create_blender_liblist(env, 'player2')
playerlist += B.create_blender_liblist(env, 'intern')
playerlist += B.create_blender_liblist(env, 'extern')
- env.BlenderProg(B.root_build_dir, "blenderplayer", playerlist + thestatlibs + dobj, thesyslibs, [B.root_build_dir+'/lib'] + thelibincs, 'blenderplayer')
+ env.BlenderProg(B.root_build_dir, "blenderplayer", dobj + playerlist + thestatlibs, thesyslibs, [B.root_build_dir+'/lib'] + thelibincs, 'blenderplayer')
##### Now define some targets
diff --git a/build_files/cmake/FindPythonLibsUnix.cmake b/build_files/cmake/FindPythonLibsUnix.cmake
index 0752de4ce3c..90bd79a924a 100644
--- a/build_files/cmake/FindPythonLibsUnix.cmake
+++ b/build_files/cmake/FindPythonLibsUnix.cmake
@@ -18,10 +18,18 @@ set(_Python_ABI_FLAGS
"m;mu;u; ")
string(REPLACE "." "" _PYTHON_VERSION_NO_DOTS ${PYTHON_VERSION})
+
set(_Python_PATHS
- "$ENV{HOME}/py${_PYTHON_VERSION_NO_DOTS}" "/opt/py${_PYTHON_VERSION_NO_DOTS}" "/usr" "/usr/local")
+ "$ENV{HOME}/py${_PYTHON_VERSION_NO_DOTS}"
+ "/opt/py${_PYTHON_VERSION_NO_DOTS}"
+ "/usr"
+ "/usr/local"
+)
-if(NOT DEFINED PYTHON_INCLUDE_DIRS)
+if(NOT DEFINED PYTHON_INCLUDE_DIRS OR
+ NOT DEFINED PYTHON_LIBRARY OR
+ NOT DEFINED PYTHON_LIBPATH)
+
message(STATUS "Looking for include Python.h")
set(_Found_PYTHON_H OFF)
@@ -53,20 +61,29 @@ if(NOT DEFINED PYTHON_INCLUDE_DIRS)
if(NOT _Found_PYTHON_H)
message(FATAL_ERROR "Python.h not found")
endif()
+
+ unset(_Found_PYTHON_H)
+ unset(_Python_HEADER)
+ unset(_CURRENT_ABI_FLAGS)
+ unset(_CURRENT_PATH)
+
+
+ set(PYTHON_INCLUDE_DIRS "${PYTHON}/include/python${PYTHON_VERSION}${PYTHON_ABI_FLAGS}" CACHE STRING "")
+ mark_as_advanced(PYTHON_INCLUDE_DIRS)
+ set(PYTHON_LIBRARY "python${PYTHON_VERSION}${PYTHON_ABI_FLAGS}" CACHE STRING "")
+ mark_as_advanced(PYTHON_LIBRARY)
+ set(PYTHON_LIBPATH ${PYTHON}/lib CACHE STRING "")
+ mark_as_advanced(PYTHON_LIBPATH)
+ # set(PYTHON_BINARY ${PYTHON_EXECUTABLE} CACHE STRING "")
endif()
+unset(_Python_ABI_FLAGS)
+unset(_Python_PATHS)
+
#=============================================================================
# now the python versions are found
-set(PYTHON_INCLUDE_DIRS "${PYTHON}/include/python${PYTHON_VERSION}${PYTHON_ABI_FLAGS}" CACHE STRING "")
-mark_as_advanced(PYTHON_INCLUDE_DIRS)
-set(PYTHON_LIBRARY "python${PYTHON_VERSION}${PYTHON_ABI_FLAGS}" CACHE STRING "")
-mark_as_advanced(PYTHON_LIBRARY)
-set(PYTHON_LIBPATH ${PYTHON}/lib CACHE STRING "")
-mark_as_advanced(PYTHON_LIBPATH)
-# set(PYTHON_BINARY ${PYTHON_EXECUTABLE} CACHE STRING "")
-
if(NOT EXISTS "${PYTHON_INCLUDE_DIRS}/Python.h")
message(FATAL_ERROR " Missing python header: ${PYTHON_INCLUDE_DIRS}/Python.h")
endif()
diff --git a/build_files/cmake/cmake_consistency_check.py b/build_files/cmake/cmake_consistency_check.py
index f55b2e95d5e..8dbfadb1187 100755
--- a/build_files/cmake/cmake_consistency_check.py
+++ b/build_files/cmake/cmake_consistency_check.py
@@ -23,15 +23,16 @@
# <pep8 compliant>
-IGNORE = \
- "/test/",\
- "/decimate_glut_test/",\
- "/BSP_GhostTest/",\
- "/release/",\
- "/xembed/",\
- "/decimation/intern/future/",\
- "/TerraplayNetwork/",\
- "/ik_glut_test/"
+IGNORE = (
+ "/test/",
+ "/decimate_glut_test/",
+ "/BSP_GhostTest/",
+ "/release/",
+ "/xembed/",
+ "/decimation/intern/future/",
+ "/TerraplayNetwork/",
+ "/ik_glut_test/",
+ )
import os
from os.path import join, dirname, normpath, abspath, splitext
@@ -104,7 +105,7 @@ def cmake_get_src(f):
found = True
break
- if "list(APPEND SRC" in l:
+ if "list(APPEND SRC" in l or ('list(APPEND ' in l and l.endswith("SRC")):
if l.endswith(")"):
raise Exception("strict formatting not kept 'list(APPEND SRC...)' on 1 line %s:%d" % (f, i))
found = True
@@ -136,7 +137,9 @@ def cmake_get_src(f):
if not l:
pass
elif l.startswith("$"):
- print("Cant use var '%s' %s:%d" % (l, f, i))
+ # assume if it ends with SRC we know about it
+ if not l.split("}")[0].endswith("SRC"):
+ print("Can't use var '%s' %s:%d" % (l, f, i))
elif len(l.split()) > 1:
raise Exception("Multi-line define '%s' %s:%d" % (l, f, i))
else:
diff --git a/build_files/cmake/example_scripts/cmake_linux_install.sh b/build_files/cmake/example_scripts/cmake_linux_install.sh
index 7770efcf392..504218f91a6 100755
--- a/build_files/cmake/example_scripts/cmake_linux_install.sh
+++ b/build_files/cmake/example_scripts/cmake_linux_install.sh
@@ -17,7 +17,7 @@ cd ~/blender-svn/build-cmake
# cmake without copying files for fast rebuilds
# the files from svn will be used in place
-cmake ../blender -DWITH_INSTALL:BOOL=FALSE
+cmake ../blender
# make blender, will take some time
make
diff --git a/build_files/cmake/macros.cmake b/build_files/cmake/macros.cmake
index 265d5072205..8189769cbbc 100644
--- a/build_files/cmake/macros.cmake
+++ b/build_files/cmake/macros.cmake
@@ -5,22 +5,28 @@
# use it instead of include_directories()
macro(blender_include_dirs
includes)
-
- foreach(inc ${ARGV})
- get_filename_component(abs_inc ${inc} ABSOLUTE)
- list(APPEND all_incs ${abs_inc})
+ set(_ALL_INCS "")
+ foreach(_INC ${ARGV})
+ get_filename_component(_ABS_INC ${_INC} ABSOLUTE)
+ list(APPEND _ALL_INCS ${_ABS_INC})
endforeach()
- include_directories(${all_incs})
+ include_directories(${_ALL_INCS})
+ unset(_INC)
+ unset(_ABS_INC)
+ unset(_ALL_INCS)
endmacro()
macro(blender_include_dirs_sys
includes)
-
- foreach(inc ${ARGV})
- get_filename_component(abs_inc ${inc} ABSOLUTE)
- list(APPEND all_incs ${abs_inc})
+ set(_ALL_INCS "")
+ foreach(_INC ${ARGV})
+ get_filename_component(_ABS_INC ${_INC} ABSOLUTE)
+ list(APPEND _ALL_INCS ${_ABS_INC})
endforeach()
- include_directories(SYSTEM ${all_incs})
+ include_directories(SYSTEM ${_ALL_INCS})
+ unset(_INC)
+ unset(_ABS_INC)
+ unset(_ALL_INCS)
endmacro()
macro(blender_source_group
@@ -29,14 +35,17 @@ macro(blender_source_group
# Group by location on disk
source_group("Source Files" FILES CMakeLists.txt)
- foreach(SRC ${sources})
- get_filename_component(SRC_EXT ${SRC} EXT)
- if(${SRC_EXT} MATCHES ".h" OR ${SRC_EXT} MATCHES ".hpp")
- source_group("Header Files" FILES ${SRC})
+ foreach(_SRC ${sources})
+ get_filename_component(_SRC_EXT ${_SRC} EXT)
+ if(${_SRC_EXT} MATCHES ".h" OR ${_SRC_EXT} MATCHES ".hpp")
+ source_group("Header Files" FILES ${_SRC})
else()
- source_group("Source Files" FILES ${SRC})
+ source_group("Source Files" FILES ${_SRC})
endif()
endforeach()
+
+ unset(_SRC)
+ unset(_SRC_EXT)
endmacro()
@@ -196,10 +205,11 @@ macro(setup_liblinks
endif()
if(WITH_IMAGE_OPENEXR)
if(WIN32 AND NOT UNIX)
- foreach(loop_var ${OPENEXR_LIB})
- target_link_libraries(${target} debug ${loop_var}_d)
- target_link_libraries(${target} optimized ${loop_var})
+ foreach(_LOOP_VAR ${OPENEXR_LIB})
+ target_link_libraries(${target} debug ${_LOOP_VAR}_d)
+ target_link_libraries(${target} optimized ${_LOOP_VAR})
endforeach()
+ unset(_LOOP_VAR)
else()
target_link_libraries(${target} ${OPENEXR_LIB})
endif()
@@ -212,10 +222,11 @@ macro(setup_liblinks
endif()
if(WITH_OPENCOLLADA)
if(WIN32 AND NOT UNIX)
- foreach(loop_var ${OPENCOLLADA_LIB})
- target_link_libraries(${target} debug ${loop_var}_d)
- target_link_libraries(${target} optimized ${loop_var})
+ foreach(_LOOP_VAR ${OPENCOLLADA_LIB})
+ target_link_libraries(${target} debug ${_LOOP_VAR}_d)
+ target_link_libraries(${target} optimized ${_LOOP_VAR})
endforeach()
+ unset(_LOOP_VAR)
target_link_libraries(${target} debug ${PCRE_LIB}_d)
target_link_libraries(${target} optimized ${PCRE_LIB})
if(EXPAT_LIB)
@@ -472,4 +483,13 @@ macro(blender_project_hack_post)
unset(_reset_standard_cflags_rel)
unset(_reset_standard_cxxflags_rel)
+
+ # ------------------------------------------------------------------
+ # workaround for omission in cmake 2.8.4's GNU.cmake, fixed in 2.8.5
+ if(CMAKE_COMPILER_IS_GNUCC)
+ if(NOT DARWIN)
+ set(CMAKE_INCLUDE_SYSTEM_FLAG_C "-isystem ")
+ endif()
+ endif()
+
endmacro()
diff --git a/build_files/scons/config/win32-vc-config.py b/build_files/scons/config/win32-vc-config.py
index 65076be85ed..b5d44db8a92 100644
--- a/build_files/scons/config/win32-vc-config.py
+++ b/build_files/scons/config/win32-vc-config.py
@@ -35,7 +35,7 @@ BF_LIBSAMPLERATE_LIBPATH = '${BF_LIBSAMPLERATE}/lib'
WITH_BF_JACK = False
BF_JACK = LIBDIR + '/jack'
-BF_JACK_INC = '${BF_JACK}/include'
+BF_JACK_INC = '${BF_JACK}/include ${BF_FFMPEG}/include/msvc'
BF_JACK_LIB = 'libjack'
BF_JACK_LIBPATH = '${BF_JACK}/lib'
@@ -118,7 +118,7 @@ BF_FREETYPE_INC = '${BF_FREETYPE}/include ${BF_FREETYPE}/include/freetype2'
BF_FREETYPE_LIB = 'freetype2ST'
BF_FREETYPE_LIBPATH = '${BF_FREETYPE}/lib'
-WITH_BF_QUICKTIME = True # -DWITH_QUICKTIME
+WITH_BF_QUICKTIME = False # -DWITH_QUICKTIME
BF_QUICKTIME = LIBDIR + '/QTDevWin'
BF_QUICKTIME_INC = '${BF_QUICKTIME}/CIncludes'
BF_QUICKTIME_LIB = 'qtmlClient'
diff --git a/build_files/scons/config/win64-vc-config.py b/build_files/scons/config/win64-vc-config.py
index 2c990941764..3332a560ed2 100644
--- a/build_files/scons/config/win64-vc-config.py
+++ b/build_files/scons/config/win64-vc-config.py
@@ -170,7 +170,7 @@ CCFLAGS = ['/nologo', '/Ob1', '/J', '/W0', '/Gd', '/we4013', '/wd4018', '/wd4244
CXXFLAGS = ['/EHsc']
BGE_CXXFLAGS = ['/O2', '/EHsc', '/GR', '/fp:fast']
-BF_DEBUG_CCFLAGS = ['/Zi', '/FR${TARGET}.sbr']
+BF_DEBUG_CCFLAGS = ['/Zi', '/FR${TARGET}.sbr', '/Od']
CPPFLAGS = ['-DWIN32', '-D_CONSOLE', '-D_LIB', '-DFTGL_LIBRARY_STATIC', '-D_CRT_SECURE_NO_DEPRECATE']
REL_CFLAGS = ['-O2', '-DNDEBUG']
diff --git a/build_files/scons/tools/Blender.py b/build_files/scons/tools/Blender.py
index 8dbed82ed84..50f43a03b8b 100644
--- a/build_files/scons/tools/Blender.py
+++ b/build_files/scons/tools/Blender.py
@@ -258,7 +258,10 @@ def setup_syslibs(lenv):
syslibs += Split(lenv['BF_PTHREADS_LIB'])
if lenv['WITH_BF_COLLADA']:
syslibs.append(lenv['BF_PCRE_LIB'])
- syslibs += Split(lenv['BF_OPENCOLLADA_LIB'])
+ if lenv['BF_DEBUG']:
+ syslibs += [colladalib+'_d' for colladalib in Split(lenv['BF_OPENCOLLADA_LIB'])]
+ else:
+ syslibs += Split(lenv['BF_OPENCOLLADA_LIB'])
syslibs.append(lenv['BF_EXPAT_LIB'])
if not lenv['WITH_BF_STATICLIBSAMPLERATE']:
@@ -287,6 +290,50 @@ def propose_priorities():
print "\t\t",new_priority, v
new_priority += 5
+# emits the necessary file objects for creator.c, to be used in creating
+# the final blender executable
+def creator(env):
+ sources = ['creator.c']# + Blender.buildinfo(env, "dynamic") + Blender.resources
+
+ incs = ['#/intern/guardedalloc', '#/source/blender/blenlib', '#/source/blender/blenkernel', '#/source/blender/editors/include', '#/source/blender/blenloader', '#/source/blender/imbuf', '#/source/blender/renderconverter', '#/source/blender/render/extern/include', '#/source/blender/windowmanager', '#/source/blender/makesdna', '#/source/blender/makesrna', '#/source/gameengine/BlenderRoutines', '#/extern/glew/include', '#/source/blender/gpu', env['BF_OPENGL_INC']]
+
+ defs = []
+ if env['WITH_BF_QUICKTIME']:
+ incs.append(env['BF_QUICKTIME_INC'])
+ defs.append('WITH_QUICKTIME')
+
+ if env['WITH_BF_BINRELOC']:
+ incs.append('#/extern/binreloc/include')
+ defs.append('WITH_BINRELOC')
+
+ if env['WITH_BF_OPENEXR']:
+ defs.append('WITH_OPENEXR')
+
+ if env['WITH_BF_TIFF']:
+ defs.append('WITH_TIFF')
+
+ if not env['WITH_BF_SDL']:
+ defs.append('DISABLE_SDL')
+
+ if env['WITH_BF_PYTHON']:
+ incs.append('#/source/blender/python')
+ defs.append('WITH_PYTHON')
+ if env['BF_DEBUG']:
+ defs.append('_DEBUG')
+
+ if env['BF_BUILDINFO']:
+ defs.append('BUILD_DATE')
+ defs.append('NAN_BUILDINFO')
+
+ if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'):
+ incs.append(env['BF_PTHREADS_INC'])
+
+ env.Append(CPPDEFINES=defs)
+ env.Append(CPPPATH=incs)
+ obj = [env.Object(root_build_dir+'source/creator/creator/creator', ['#source/creator/creator.c'])]
+
+ return obj
+
## TODO: see if this can be made in an emitter
def buildinfo(lenv, build_type):
"""
@@ -324,7 +371,7 @@ def buildinfo(lenv, build_type):
lenv.Append (CPPPATH = [root_build_dir+'source/blender/blenkernel'])
- obj = [lenv.Object (root_build_dir+'source/creator/%s_buildinfo'%build_type, [root_build_dir+'source/creator/buildinfo.c'])]
+ obj = [lenv.Object (root_build_dir+'source/creator/%s_buildinfo'%build_type, ['#source/creator/buildinfo.c'])]
return obj
@@ -714,23 +761,19 @@ class BlenderEnvironment(SConsEnvironment):
global vcp
print bc.HEADER+'Configuring program '+bc.ENDC+bc.OKGREEN+progname+bc.ENDC
lenv = self.Clone()
+ lenv.Append(LINKFLAGS = lenv['PLATFORM_LINKFLAGS'])
if lenv['OURPLATFORM'] in ('win32-vc', 'cygwin', 'win64-vc'):
- lenv.Append(LINKFLAGS = lenv['PLATFORM_LINKFLAGS'])
- lenv.Append(LINKFLAGS = ['/FORCE:MULTIPLE'])
if lenv['BF_DEBUG']:
- lenv.Prepend(LINKFLAGS = ['/DEBUG','/PDB:'+progname+'.pdb'])
+ lenv.Prepend(LINKFLAGS = ['/DEBUG','/PDB:'+progname+'.pdb','/NODEFAULTLIB:libcmt'])
if lenv['OURPLATFORM']=='linux2':
- lenv.Append(LINKFLAGS = lenv['PLATFORM_LINKFLAGS'])
if lenv['WITH_BF_PYTHON']:
lenv.Append(LINKFLAGS = lenv['BF_PYTHON_LINKFLAGS'])
if lenv['OURPLATFORM']=='sunos5':
- lenv.Append(LINKFLAGS = lenv['PLATFORM_LINKFLAGS'])
if lenv['WITH_BF_PYTHON']:
lenv.Append(LINKFLAGS = lenv['BF_PYTHON_LINKFLAGS'])
if lenv['CXX'].endswith('CC'):
lenv.Replace(LINK = '$CXX')
if lenv['OURPLATFORM']=='darwin':
- lenv.Append(LINKFLAGS = lenv['PLATFORM_LINKFLAGS'])
if lenv['WITH_BF_PYTHON']:
lenv.Append(LINKFLAGS = lenv['BF_PYTHON_LINKFLAGS'])
lenv.Append(LINKFLAGS = lenv['BF_OPENGL_LINKFLAGS'])
diff --git a/doc/manpage/blender.1 b/doc/manpage/blender.1
index c27cc98f08b..ddf3a79b104 100644
--- a/doc/manpage/blender.1
+++ b/doc/manpage/blender.1
@@ -1,4 +1,4 @@
-.TH "BLENDER" "1" "April 05, 2011" "Blender Blender 2\&.56 (sub 6)"
+.TH "BLENDER" "1" "June 03, 2011" "Blender Blender 2\&.57 (sub 1)"
.SH NAME
blender \- a 3D modelling and rendering package
@@ -15,7 +15,7 @@ Use Blender to create TV commercials, to make technical visualizations, business
http://www.blender.org
.SH OPTIONS
-Blender 2.56 (sub 6)
+Blender 2.57 (sub 1)
Usage: blender [args ...] [file] [args ...]
.br
.SS "Render Options:"
@@ -160,6 +160,12 @@ Force opening without borders
Open with lower left corner at <sx>, <sy> and width and height as <w>, <h>
.br
+.TP
+.B \-con or \-\-start\-console
+.br
+Start with the console window open (ignored if \-b is set)
+.br
+
.IP
.SS "Game Engine Specific Options:"
@@ -191,7 +197,7 @@ Turn debugging on
.br
* Disables mouse grab (to interact with a debugger in some cases)
.br
-* Keeps python sys.stdin rather then setting it to None
+* Keeps python sys.stdin rather than setting it to None
.br
.TP
@@ -211,12 +217,6 @@ Skip reading the "startup.blend" in the users home directory
.IP
.TP
-.B \-\-env\-system\-config
-.br
-Set the BLENDER_SYSTEM_CONFIG environment variable
-.br
-
-.TP
.B \-\-env\-system\-datafiles
.br
Set the BLENDER_SYSTEM_DATAFILES environment variable
@@ -281,7 +281,7 @@ Print this help text and exit
.TP
.B \-y or \-\-enable\-autoexec
.br
-Enable automatic python script execution (default)
+Enable automatic python script execution, (default)
.br
.TP
@@ -376,7 +376,6 @@ Arguments are executed in the order they are given. eg
.br
.SH "ENVIRONMENT VARIABLES"
\fIBLENDER_USER_CONFIG\fR Directory for user configuration files.
- \fIBLENDER_SYSTEM_CONFIG\fR Directory for system wide configuration files.
\fIBLENDER_USER_SCRIPTS\fR Directory for user scripts.
\fIBLENDER_SYSTEM_SCRIPTS\fR Directory for system wide scripts.
\fIBLENDER_USER_DATAFILES\fR Directory for user data files (icons, translations, ..).
diff --git a/doc/python_api/rst/bge.logic.rst b/doc/python_api/rst/bge.logic.rst
index 20a3a68b387..0af4a1184d6 100644
--- a/doc/python_api/rst/bge.logic.rst
+++ b/doc/python_api/rst/bge.logic.rst
@@ -345,9 +345,9 @@ Utility functions
.. function:: getAverageFrameRate()
- Gets the estimated average framerate
-
- :return: The estimed average framerate in frames per second
+ Gets the estimated/average framerate for all the active scenes, not only the current scene.
+
+ :return: The estimated average framerate in frames per second
:rtype: float
.. function:: getBlendFileList(path = "//")
diff --git a/doc/python_api/rst/bge.types.rst b/doc/python_api/rst/bge.types.rst
index b54eca07e55..e42b362c771 100644
--- a/doc/python_api/rst/bge.types.rst
+++ b/doc/python_api/rst/bge.types.rst
@@ -710,6 +710,12 @@ Game Engine bge.types Module
Applies changes to a camera.
+ .. attribute:: damping
+
+ strength of of the camera following movement.
+
+ :type: float
+
.. attribute:: min
minimum distance to the target object maintained by the actuator.
diff --git a/intern/elbeem/extern/elbeem.h b/intern/elbeem/extern/elbeem.h
index f5538df8805..6df08ccebd2 100644
--- a/intern/elbeem/extern/elbeem.h
+++ b/intern/elbeem/extern/elbeem.h
@@ -77,6 +77,10 @@ typedef struct elbeemSimulationSettings {
/* boundary types and settings for domain walls */
short domainobsType;
float domainobsPartslip;
+
+ /* what surfaces to generate */
+ int mFsSurfGenSetting;
+
/* generate speed vectors for vertices (e.g. for image based motion blur)*/
short generateVertexVectors;
/* strength of surface smoothing */
@@ -108,10 +112,12 @@ typedef struct elbeemSimulationSettings {
#define OB_FLUIDSIM_PARTICLE 64
#define OB_FLUIDSIM_CONTROL 128
-// defines for elbeemMesh->obstacleType below
+// defines for elbeemMesh->obstacleType below (low bits) high bits (>=64) are reserved for mFsSurfGenSetting flags which are defined in solver_class.h
#define FLUIDSIM_OBSTACLE_NOSLIP 1
#define FLUIDSIM_OBSTACLE_PARTSLIP 2
#define FLUIDSIM_OBSTACLE_FREESLIP 3
+#define FLUIDSIM_FSSG_NOOBS 64
+
#define OB_VOLUMEINIT_VOLUME 1
#define OB_VOLUMEINIT_SHELL 2
diff --git a/intern/elbeem/intern/simulation_object.cpp b/intern/elbeem/intern/simulation_object.cpp
index 2544b8fe29c..87828b26088 100644
--- a/intern/elbeem/intern/simulation_object.cpp
+++ b/intern/elbeem/intern/simulation_object.cpp
@@ -181,6 +181,9 @@ int SimulationObject::initializeLbmSimulation(ntlRenderGlobals *glob)
mpLbm->setGenerateParticles(mpElbeemSettings->generateParticles);
// set initial particles
mpParts->setNumInitialParticles(mpElbeemSettings->numTracerParticles);
+
+ // surface generation flag
+ mpLbm->setSurfGenSettings(mpElbeemSettings->mFsSurfGenSetting);
string dinitType = string("no");
if (mpElbeemSettings->domainobsType==FLUIDSIM_OBSTACLE_PARTSLIP) dinitType = string("part");
diff --git a/intern/elbeem/intern/solver_class.h b/intern/elbeem/intern/solver_class.h
index 8662ac3f12a..1548aaa19bc 100644
--- a/intern/elbeem/intern/solver_class.h
+++ b/intern/elbeem/intern/solver_class.h
@@ -308,6 +308,9 @@ class LbmFsgrSolver :
//! for raytracing, preprocess
void prepareVisualization( void );
+ /* surface generation settings */
+ virtual void setSurfGenSettings(short value);
+
protected:
//! internal quick print function (for debugging)
diff --git a/intern/elbeem/intern/solver_init.cpp b/intern/elbeem/intern/solver_init.cpp
index 899b1e0ecbc..7e9f5e7f420 100644
--- a/intern/elbeem/intern/solver_init.cpp
+++ b/intern/elbeem/intern/solver_init.cpp
@@ -539,6 +539,15 @@ void LbmFsgrSolver::parseAttrList()
/******************************************************************************
+ * (part of enabling chapter 6 of "Free Surface Flows with Moving and Deforming Objects for LBM")
+ *****************************************************************************/
+void LbmFsgrSolver::setSurfGenSettings(short value)
+{
+ mFsSurfGenSetting = value;
+}
+
+
+/******************************************************************************
* Initialize omegas and forces on all levels (for init/timestep change)
*****************************************************************************/
void LbmFsgrSolver::initLevelOmegas()
diff --git a/intern/elbeem/intern/solver_interface.h b/intern/elbeem/intern/solver_interface.h
index 71b347d683d..8f3181a307d 100644
--- a/intern/elbeem/intern/solver_interface.h
+++ b/intern/elbeem/intern/solver_interface.h
@@ -271,6 +271,9 @@ class LbmSolverInterface
/*! debug object display */
virtual vector<ntlGeometryObject*> getDebugObjects() { vector<ntlGeometryObject*> empty(0); return empty; }
+ /* surface generation settings */
+ virtual void setSurfGenSettings(short value) = 0;
+
#if LBM_USE_GUI==1
/*! show simulation info */
virtual void debugDisplay(int) = 0;
diff --git a/intern/ghost/CMakeLists.txt b/intern/ghost/CMakeLists.txt
index 065aa68dd3d..922f6918392 100644
--- a/intern/ghost/CMakeLists.txt
+++ b/intern/ghost/CMakeLists.txt
@@ -89,7 +89,42 @@ set(SRC
intern/GHOST_WindowManager.h
)
-if(APPLE)
+if(WITH_HEADLESS)
+ list(APPEND SRC
+ intern/GHOST_DisplayManagerNULL.h
+ intern/GHOST_SystemNULL.h
+ intern/GHOST_WindowNULL.h
+ )
+ add_definitions(-DWITH_HEADLESS)
+
+ # ack, this is still system dependant
+ if(APPLE)
+ if(WITH_COCOA)
+ list(APPEND SRC
+ intern/GHOST_SystemPathsCocoa.mm
+ intern/GHOST_SystemPathsCocoa.h
+ )
+ else()
+ list(APPEND SRC
+ intern/GHOST_SystemPathsCarbon.cpp
+ intern/GHOST_SystemPathsCarbon.h
+ )
+ endif()
+ elseif(UNIX)
+ list(APPEND SRC
+ intern/GHOST_SystemPathsX11.cpp
+ intern/GHOST_SystemPathsX11.h
+ )
+ elseif(WIN32)
+
+ list(APPEND SRC
+ intern/GHOST_SystemPathsWin32.cpp
+
+ intern/GHOST_SystemPathsWin32.h
+ )
+ endif()
+
+elseif(APPLE)
if(WITH_COCOA)
list(APPEND SRC
intern/GHOST_DisplayManagerCocoa.mm
diff --git a/intern/ghost/intern/GHOST_DisplayManagerNULL.h b/intern/ghost/intern/GHOST_DisplayManagerNULL.h
new file mode 100644
index 00000000000..ba4a36ee3d1
--- /dev/null
+++ b/intern/ghost/intern/GHOST_DisplayManagerNULL.h
@@ -0,0 +1,51 @@
+/*
+ * $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.
+ *
+ * Contributor(s): Campbell Barton
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file ghost/intern/GHOST_DisplayManagerNULL.h
+ * \ingroup GHOST
+ * Declaration of GHOST_DisplayManagerNULL class.
+ */
+
+#ifndef _GHOST_DISPLAY_MANAGER_NULL_H_
+#define _GHOST_DISPLAY_MANAGER_NULL_H_
+
+#include "GHOST_DisplayManager.h"
+#include "GHOST_SystemNULL.h"
+
+class GHOST_SystemNULL;
+
+class GHOST_DisplayManagerNULL : public GHOST_DisplayManager
+{
+public:
+ GHOST_DisplayManagerNULL( GHOST_SystemNULL *system ) : GHOST_DisplayManager(), m_system(system) { /* nop */ }
+ GHOST_TSuccess getNumDisplays( GHOST_TUns8& numDisplays ) const { return GHOST_kFailure; }
+ GHOST_TSuccess getNumDisplaySettings( GHOST_TUns8 display, GHOST_TInt32& numSettings ) const{ return GHOST_kFailure; }
+ GHOST_TSuccess getDisplaySetting( GHOST_TUns8 display, GHOST_TInt32 index, GHOST_DisplaySetting& setting ) const { return GHOST_kFailure; }
+ GHOST_TSuccess getCurrentDisplaySetting( GHOST_TUns8 display, GHOST_DisplaySetting& setting ) const { return getDisplaySetting(display,GHOST_TInt32(0),setting); }
+ GHOST_TSuccess setCurrentDisplaySetting( GHOST_TUns8 display, const GHOST_DisplaySetting& setting ){ return GHOST_kSuccess; }
+
+private :
+ GHOST_SystemNULL * m_system;
+};
+
+#endif /* _GHOST_DISPLAY_MANAGER_NULL_H_ */
diff --git a/intern/ghost/intern/GHOST_ISystem.cpp b/intern/ghost/intern/GHOST_ISystem.cpp
index 040164e2c40..7f170d2e876 100644
--- a/intern/ghost/intern/GHOST_ISystem.cpp
+++ b/intern/ghost/intern/GHOST_ISystem.cpp
@@ -41,7 +41,9 @@
#include "GHOST_ISystem.h"
-#ifdef WIN32
+#ifdef WITH_HEADLESS
+# include "GHOST_SystemNULL.h"
+#elif defined(WIN32)
# include "GHOST_SystemWin32.h"
#else
# ifdef __APPLE__
@@ -63,7 +65,9 @@ GHOST_TSuccess GHOST_ISystem::createSystem()
{
GHOST_TSuccess success;
if (!m_system) {
-#ifdef WIN32
+#ifdef WITH_HEADLESS
+ m_system = new GHOST_SystemNULL();
+#elif defined(WIN32)
m_system = new GHOST_SystemWin32 ();
#else
# ifdef __APPLE__
diff --git a/intern/ghost/intern/GHOST_NDOFManager.cpp b/intern/ghost/intern/GHOST_NDOFManager.cpp
index 95626ec26ea..7721b1708f9 100644
--- a/intern/ghost/intern/GHOST_NDOFManager.cpp
+++ b/intern/ghost/intern/GHOST_NDOFManager.cpp
@@ -81,7 +81,9 @@ GHOST_NDOFManager::deviceOpen(GHOST_IWindow* window,
#if 0
printf("%i client \n", Pid);
#endif
- #if defined(_WIN32) || defined(__APPLE__)
+ #if defined(WITH_HEADLESS)
+ /* do nothing */
+ #elif defined(_WIN32) || defined(__APPLE__)
m_DeviceHandle = ndofDeviceOpen((void *)&currentNdofValues);
#else
GHOST_SystemX11 *sys;
diff --git a/intern/ghost/intern/GHOST_SystemNULL.h b/intern/ghost/intern/GHOST_SystemNULL.h
new file mode 100644
index 00000000000..3bc68b45b0d
--- /dev/null
+++ b/intern/ghost/intern/GHOST_SystemNULL.h
@@ -0,0 +1,93 @@
+/*
+ * $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.
+ *
+ * Contributor(s): Campbell Barton
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file ghost/intern/GHOST_SystemNULL.h
+ * \ingroup GHOST
+ * Declaration of GHOST_SystemNULL class.
+ */
+
+#ifndef _GHOST_SYSTEM_NULL_H_
+#define _GHOST_SYSTEM_NULL_H_
+
+#include "GHOST_System.h"
+#include "../GHOST_Types.h"
+#include "GHOST_DisplayManagerNULL.h"
+#include "GHOST_WindowNULL.h"
+
+class GHOST_WindowNULL;
+
+class GHOST_SystemNULL : public GHOST_System {
+public:
+
+ GHOST_SystemNULL( ) : GHOST_System() { /* nop */ }
+ ~GHOST_SystemNULL() { /* nop */ }
+ bool processEvents(bool waitForEvent) { return false; }
+ int toggleConsole(int action) { return 0; }
+ GHOST_TSuccess getModifierKeys(GHOST_ModifierKeys& keys) const { return GHOST_kSuccess; }
+ GHOST_TSuccess getButtons(GHOST_Buttons& buttons) const { return GHOST_kSuccess; }
+ GHOST_TUns8 *getClipboard(bool selection) const { return NULL; }
+ void putClipboard(GHOST_TInt8 *buffer, bool selection) const { /* nop */ }
+ GHOST_TUns64 getMilliSeconds( ) const { return 0; }
+ GHOST_TUns8 getNumDisplays( ) const { return GHOST_TUns8(1); }
+ GHOST_TSuccess getCursorPosition( GHOST_TInt32& x, GHOST_TInt32& y ) const { return GHOST_kFailure; }
+ GHOST_TSuccess setCursorPosition( GHOST_TInt32 x, GHOST_TInt32 y ) { return GHOST_kFailure; }
+ void getMainDisplayDimensions( GHOST_TUns32& width, GHOST_TUns32& height ) const { /* nop */ }
+
+ GHOST_TSuccess init() {
+ GHOST_TSuccess success = GHOST_System::init();
+
+ if (success) {
+ m_displayManager = new GHOST_DisplayManagerNULL(this);
+
+ if (m_displayManager) {
+ return GHOST_kSuccess;
+ }
+ }
+
+ return GHOST_kFailure;
+ }
+
+ GHOST_IWindow* createWindow(
+ const STR_String& title,
+ GHOST_TInt32 left,
+ GHOST_TInt32 top,
+ GHOST_TUns32 width,
+ GHOST_TUns32 height,
+ GHOST_TWindowState state,
+ GHOST_TDrawingContextType type,
+ bool stereoVisual,
+ const GHOST_TUns16 numOfAASamples,
+ const GHOST_TEmbedderWindowID parentWindow
+ ) {
+ return new GHOST_WindowNULL (this, title, left, top, width, height, state, parentWindow, type, stereoVisual, 1);
+ }
+};
+
+#endif
+
+
+
+
+
+
+
diff --git a/intern/ghost/intern/GHOST_WindowNULL.h b/intern/ghost/intern/GHOST_WindowNULL.h
new file mode 100644
index 00000000000..0ec3c6f5700
--- /dev/null
+++ b/intern/ghost/intern/GHOST_WindowNULL.h
@@ -0,0 +1,96 @@
+/*
+ * $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.
+ *
+ * Contributor(s): Campbell Barton
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file ghost/intern/GHOST_WindowNULL.h
+ * \ingroup GHOST
+ * Declaration of GHOST_WindowNULL class.
+ */
+
+#ifndef _GHOST_WINDOWNULL_H_
+#define _GHOST_WINDOWNULL_H_
+
+#include "GHOST_Window.h"
+
+#include <map>
+
+class STR_String;
+class GHOST_SystemNULL;
+
+class GHOST_WindowNULL : public GHOST_Window
+{
+public:
+ const GHOST_TabletData* GetTabletData() { return NULL; }
+
+ GHOST_WindowNULL(
+ GHOST_SystemNULL *system,
+ const STR_String& title,
+ GHOST_TInt32 left,
+ GHOST_TInt32 top,
+ GHOST_TUns32 width,
+ GHOST_TUns32 height,
+ GHOST_TWindowState state,
+ const GHOST_TEmbedderWindowID parentWindow,
+ GHOST_TDrawingContextType type,
+ const bool stereoVisual,
+ const GHOST_TUns16 numOfAASamples
+ ) :
+ GHOST_Window(title,left,top,width,height,state,type,stereoVisual,numOfAASamples),
+ m_system (system)
+ {
+ setTitle(title);
+ }
+
+protected:
+ GHOST_TSuccess installDrawingContext( GHOST_TDrawingContextType type ){ return GHOST_kSuccess; }
+ GHOST_TSuccess removeDrawingContext( ){ return GHOST_kSuccess; }
+ GHOST_TSuccess setWindowCursorGrab( GHOST_TGrabCursorMode mode ){ return GHOST_kSuccess; }
+ GHOST_TSuccess setWindowCursorShape( GHOST_TStandardCursor shape ){ return GHOST_kSuccess; }
+ GHOST_TSuccess setWindowCustomCursorShape( GHOST_TUns8 bitmap[16][2], GHOST_TUns8 mask[16][2], int hotX, int hotY ) { return GHOST_kSuccess; }
+ GHOST_TSuccess setWindowCustomCursorShape( GHOST_TUns8 *bitmap, GHOST_TUns8 *mask, int sizex, int sizey, int hotX, int hotY, int fg_color, int bg_color ){ return GHOST_kSuccess; }
+
+ bool getValid( ) const { return true; }
+ void setTitle( const STR_String& title ){ /* nothing */ }
+ void getTitle( STR_String& title ) const { title= "untitled"; }
+ void getWindowBounds( GHOST_Rect& bounds ) const { getClientBounds(bounds); }
+ void getClientBounds( GHOST_Rect& bounds ) const { /* nothing */ }
+ GHOST_TSuccess setClientWidth( GHOST_TUns32 width ){ return GHOST_kFailure; }
+ GHOST_TSuccess setClientHeight( GHOST_TUns32 height ){ return GHOST_kFailure; }
+ GHOST_TSuccess setClientSize( GHOST_TUns32 width, GHOST_TUns32 height ){ return GHOST_kFailure; }
+ void screenToClient( GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY ) const { outX = inX; outY = inY; }
+ void clientToScreen( GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY ) const { outX = inX; outY = inY; }
+ GHOST_TSuccess swapBuffers( ){ return GHOST_kFailure; }
+ GHOST_TSuccess activateDrawingContext( ){ return GHOST_kFailure; }
+ ~GHOST_WindowNULL( ){ /* nothing */ }
+ GHOST_TSuccess setWindowCursorVisibility( bool visible ){ return GHOST_kSuccess; }
+ GHOST_TSuccess setState(GHOST_TWindowState state) { return GHOST_kSuccess; }
+ GHOST_TWindowState getState() const { return GHOST_kWindowStateNormal; }
+ GHOST_TSuccess invalidate() { return GHOST_kSuccess; }
+ GHOST_TSuccess setOrder(GHOST_TWindowOrder order) { return GHOST_kSuccess; }
+
+
+private :
+ GHOST_SystemNULL * m_system;
+};
+
+
+#endif // _GHOST_WINDOWNULL_H_
diff --git a/release/scripts/modules/console/complete_namespace.py b/release/scripts/modules/console/complete_namespace.py
index a31280ebff0..d787fed0967 100644
--- a/release/scripts/modules/console/complete_namespace.py
+++ b/release/scripts/modules/console/complete_namespace.py
@@ -37,6 +37,11 @@ def is_dict(obj):
return hasattr(obj, 'keys') and hasattr(getattr(obj, 'keys'), '__call__')
+def is_struct_seq(obj):
+ """Returns whether obj is a structured sequence subclass: sys.float_info"""
+ return isinstance(obj, tuple) and hasattr(obj, 'n_fields')
+
+
def complete_names(word, namespace):
"""Complete variable names or attributes
@@ -174,7 +179,7 @@ def complete(word, namespace, private=True):
if type(obj) in (bool, float, int, str):
return []
# an extra char '[', '(' or '.' will be added
- if hasattr(obj, '__getitem__'):
+ if hasattr(obj, '__getitem__') and not is_struct_seq(obj):
# list or dictionary
matches = complete_indices(word, namespace, obj)
elif hasattr(obj, '__call__'):
diff --git a/release/scripts/modules/console/intellisense.py b/release/scripts/modules/console/intellisense.py
index 9352d7c14e1..072d467ff86 100644
--- a/release/scripts/modules/console/intellisense.py
+++ b/release/scripts/modules/console/intellisense.py
@@ -120,15 +120,25 @@ def expand(line, cursor, namespace, private=True):
from . import complete_calltip
matches, word, scrollback = complete_calltip.complete(line,
cursor, namespace)
+ prefix = os.path.commonprefix(matches)[len(word):]
no_calltip = False
else:
matches, word = complete(line, cursor, namespace, private)
+ prefix = os.path.commonprefix(matches)[len(word):]
if len(matches) == 1:
scrollback = ''
else:
- scrollback = ' '.join([m.split('.')[-1] for m in matches])
+ # causes blender bug [#27495] since string keys may contain '.'
+ # scrollback = ' '.join([m.split('.')[-1] for m in matches])
+ word_prefix = word + prefix
+ scrollback = ' '.join(
+ [m[len(word_prefix):]
+ if (word_prefix and m.startswith(word_prefix))
+ else m.split('.')[-1]
+ for m in matches])
+
no_calltip = True
- prefix = os.path.commonprefix(matches)[len(word):]
+
if prefix:
line = line[:cursor] + prefix + line[cursor:]
cursor += len(prefix)
diff --git a/release/scripts/modules/console_python.py b/release/scripts/modules/console_python.py
index 3048fa1d597..455eabe377b 100644
--- a/release/scripts/modules/console_python.py
+++ b/release/scripts/modules/console_python.py
@@ -80,7 +80,7 @@ def get_console(console_id):
if console_data:
console, stdout, stderr = console_data
- # XXX, bug in python 3.1.2 ? (worked in 3.1.1)
+ # XXX, bug in python 3.1.2, 3.2 ? (worked in 3.1.1)
# seems there is no way to clear StringIO objects for writing, have to make new ones each time.
import io
stdout = io.StringIO()
diff --git a/release/scripts/startup/bl_operators/object_quick_effects.py b/release/scripts/startup/bl_operators/object_quick_effects.py
index 21640fa3ee6..90b0fa0af83 100644
--- a/release/scripts/startup/bl_operators/object_quick_effects.py
+++ b/release/scripts/startup/bl_operators/object_quick_effects.py
@@ -22,10 +22,9 @@ from mathutils import Vector
import bpy
from bpy.props import BoolProperty, EnumProperty, IntProperty, FloatProperty, FloatVectorProperty
-
-class MakeFur(bpy.types.Operator):
- bl_idname = "object.make_fur"
- bl_label = "Make Fur"
+class QuickFur(bpy.types.Operator):
+ bl_idname = "object.quick_fur"
+ bl_label = "Quick Fur"
bl_options = {'REGISTER', 'UNDO'}
density = EnumProperty(items=(
@@ -79,6 +78,155 @@ class MakeFur(bpy.types.Operator):
return {'FINISHED'}
+class QuickExplode(bpy.types.Operator):
+ bl_idname = "object.quick_explode"
+ bl_label = "Quick Explode"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ style = EnumProperty(items=(
+ ('EXPLODE', "Explode", ""),
+ ('BLEND', "Blend", "")),
+ name="Explode Style",
+ description="",
+ default='EXPLODE')
+
+ amount = IntProperty(name="Amount of pieces",
+ default=100, min=2, max=10000, soft_min=2, soft_max=10000)
+
+ duration = IntProperty(name="Duration",
+ default=50, min=1, max=10000, soft_min=1, soft_max=10000)
+
+ start_frame = IntProperty(name="Start Frame",
+ default=1, min=1, max=10000, soft_min=1, soft_max=10000)
+
+ end_frame = IntProperty(name="End Frame",
+ default=10, min=1, max=10000, soft_min=1, soft_max=10000)
+
+ velocity = FloatProperty(name="Outwards Velocity",
+ default=1, min=0, max=1000, soft_min=0, soft_max=10)
+
+ fade = BoolProperty(name="Fade",
+ description="Fade the pieces over time.",
+ default=True)
+
+ invert_order = BoolProperty(name="Invert Order",
+ description="Blend objects in the opposite direction (only for Blend style explosion).",
+ default=False)
+
+ def execute(self, context):
+ fake_context = bpy.context.copy()
+ mesh_objects = [obj for obj in context.selected_objects if obj.type == 'MESH']
+
+ if self.style == 'BLEND' and len(mesh_objects) != 2:
+ self.report({'ERROR'}, "Select two mesh objects.")
+ return {'CANCELLED'}
+ elif not mesh_objects:
+ self.report({'ERROR'}, "Select at least one mesh object.")
+ return {'CANCELLED'}
+
+ for obj in mesh_objects:
+ if len(obj.particle_systems) > 0:
+ self.report({'ERROR'}, "Selected object's can't have particle systems.")
+ return {'CANCELLED'}
+
+ if self.fade:
+ tex = bpy.data.textures.new("Explode fade", 'BLEND')
+ tex.use_color_ramp = True
+
+ if self.style == 'BLEND':
+ tex.color_ramp.elements[0].position = 0.333
+ tex.color_ramp.elements[1].position = 0.666
+
+ tex.color_ramp.elements[0].color[3] = 1
+ tex.color_ramp.elements[1].color[3] = 0
+
+ if self.style == 'BLEND':
+ if self.invert_order:
+ from_obj = mesh_objects[1]
+ to_obj = mesh_objects[0]
+ else:
+ from_obj = mesh_objects[0]
+ to_obj = mesh_objects[1]
+
+ for obj in mesh_objects:
+ fake_context["object"] = obj
+ bpy.ops.object.particle_system_add(fake_context)
+
+ settings = obj.particle_systems[-1].settings
+ settings.count = self.amount
+ settings.frame_start = self.start_frame
+ settings.frame_end = self.end_frame - self.duration
+ settings.lifetime = self.duration
+ settings.normal_factor = self.velocity
+ settings.render_type = 'NONE'
+
+ bpy.ops.object.modifier_add(fake_context, type='EXPLODE')
+ explode = obj.modifiers[-1]
+ explode.use_edge_cut = True
+
+ if self.fade:
+ explode.show_dead = False
+ bpy.ops.mesh.uv_texture_add(fake_context);
+ uv = obj.data.uv_textures[-1]
+ uv.name = "Explode fade"
+ explode.particle_uv = uv.name
+
+ if len(obj.material_slots) == 0:
+ obj.data.materials.append(bpy.data.materials.new("Explode fade"))
+
+ mat = obj.data.materials[0]
+ mat.use_transparency = True
+ mat.use_transparent_shadows = True
+ mat.alpha = 0
+ mat.specular_alpha = 0
+
+ tex_slot = mat.texture_slots.add()
+
+ tex_slot.texture = tex
+ tex_slot.texture_coords = 'UV'
+ tex_slot.uv_layer = uv.name
+
+ tex_slot.use_map_alpha = True
+
+ if self.style == 'BLEND':
+ if obj == to_obj:
+ tex_slot.alpha_factor = -1
+ elem = tex.color_ramp.elements[1]
+ elem.color[0] = mat.diffuse_color[0]
+ elem.color[1] = mat.diffuse_color[1]
+ elem.color[2] = mat.diffuse_color[2]
+ else:
+ elem = tex.color_ramp.elements[0]
+ elem.color[0] = mat.diffuse_color[0]
+ elem.color[1] = mat.diffuse_color[1]
+ elem.color[2] = mat.diffuse_color[2]
+ else:
+ tex_slot.use_map_color_diffuse = False
+
+ if self.style == 'BLEND':
+ settings.physics_type = 'KEYED'
+ settings.use_emit_random = False
+ settings.rotation_mode = 'NOR'
+
+ psys = obj.particle_systems[-1]
+
+ fake_context["particle_system"] = obj.particle_systems[-1]
+ bpy.ops.particle.new_target(fake_context)
+ bpy.ops.particle.new_target(fake_context)
+
+ if obj == from_obj:
+ psys.targets[1].object = to_obj
+ else:
+ psys.targets[0].object = from_obj
+ settings.normal_factor = -self.velocity
+ explode.show_unborn = False
+ explode.show_dead = True
+ else:
+ settings.factor_random = self.velocity
+ settings.angular_velocity_factor = self.velocity/10
+
+ return {'FINISHED'}
+
def obj_bb_minmax(obj, min_co, max_co):
for i in range(0, 8):
@@ -92,9 +240,9 @@ def obj_bb_minmax(obj, min_co, max_co):
max_co[2] = max(bb_vec[2], max_co[2])
-class MakeSmoke(bpy.types.Operator):
- bl_idname = "object.make_smoke"
- bl_label = "Make Smoke"
+class QuickSmoke(bpy.types.Operator):
+ bl_idname = "object.quick_smoke"
+ bl_label = "Quick Smoke"
bl_options = {'REGISTER', 'UNDO'}
style = EnumProperty(items=(
@@ -201,9 +349,9 @@ class MakeSmoke(bpy.types.Operator):
return {'FINISHED'}
-class MakeFluid(bpy.types.Operator):
- bl_idname = "object.make_fluid"
- bl_label = "Make Fluid"
+class QuickFluid(bpy.types.Operator):
+ bl_idname = "object.quick_fluid"
+ bl_label = "Quick Fluid"
bl_options = {'REGISTER', 'UNDO'}
style = EnumProperty(items=(
@@ -293,4 +441,4 @@ class MakeFluid(bpy.types.Operator):
if self.start_baking:
bpy.ops.fluid.bake()
- return {'FINISHED'}
+ return {'FINISHED'} \ No newline at end of file
diff --git a/release/scripts/startup/bl_operators/presets.py b/release/scripts/startup/bl_operators/presets.py
index 493c51ad237..2175d7528a4 100644
--- a/release/scripts/startup/bl_operators/presets.py
+++ b/release/scripts/startup/bl_operators/presets.py
@@ -326,7 +326,7 @@ class AddPresetOperator(AddPresetBase, bpy.types.Operator):
ret = []
for prop_id, prop in operator_rna.properties.items():
- if (not prop.is_hidden) and prop_id not in properties_blacklist:
+ if (not (prop.is_hidden or prop.is_skip_save)) and prop_id not in properties_blacklist:
ret.append("op.%s" % prop_id)
return ret
diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py
index 3f4a061c4ac..fcc30ecbb4b 100644
--- a/release/scripts/startup/bl_operators/wm.py
+++ b/release/scripts/startup/bl_operators/wm.py
@@ -106,7 +106,7 @@ class WM_OT_context_set_boolean(bpy.types.Operator):
'''Set a context value.'''
bl_idname = "wm.context_set_boolean"
bl_label = "Context Set Boolean"
- bl_options = {'UNDO'}
+ bl_options = {'UNDO', 'INTERNAL'}
data_path = rna_path_prop
value = BoolProperty(name="Value",
@@ -119,7 +119,7 @@ class WM_OT_context_set_int(bpy.types.Operator): # same as enum
'''Set a context value.'''
bl_idname = "wm.context_set_int"
bl_label = "Context Set"
- bl_options = {'UNDO'}
+ bl_options = {'UNDO', 'INTERNAL'}
data_path = rna_path_prop
value = IntProperty(name="Value", description="Assign value", default=0)
@@ -132,7 +132,7 @@ class WM_OT_context_scale_int(bpy.types.Operator):
'''Scale an int context value.'''
bl_idname = "wm.context_scale_int"
bl_label = "Context Set"
- bl_options = {'UNDO'}
+ bl_options = {'UNDO', 'INTERNAL'}
data_path = rna_path_prop
value = FloatProperty(name="Value", description="Assign value", default=1.0)
@@ -168,7 +168,7 @@ class WM_OT_context_set_float(bpy.types.Operator): # same as enum
'''Set a context value.'''
bl_idname = "wm.context_set_float"
bl_label = "Context Set Float"
- bl_options = {'UNDO'}
+ bl_options = {'UNDO', 'INTERNAL'}
data_path = rna_path_prop
value = FloatProperty(name="Value",
@@ -182,7 +182,7 @@ class WM_OT_context_set_string(bpy.types.Operator): # same as enum
'''Set a context value.'''
bl_idname = "wm.context_set_string"
bl_label = "Context Set String"
- bl_options = {'UNDO'}
+ bl_options = {'UNDO', 'INTERNAL'}
data_path = rna_path_prop
value = StringProperty(name="Value",
@@ -195,7 +195,7 @@ class WM_OT_context_set_enum(bpy.types.Operator):
'''Set a context value.'''
bl_idname = "wm.context_set_enum"
bl_label = "Context Set Enum"
- bl_options = {'UNDO'}
+ bl_options = {'UNDO', 'INTERNAL'}
data_path = rna_path_prop
value = StringProperty(name="Value",
@@ -209,7 +209,7 @@ class WM_OT_context_set_value(bpy.types.Operator):
'''Set a context value.'''
bl_idname = "wm.context_set_value"
bl_label = "Context Set Value"
- bl_options = {'UNDO'}
+ bl_options = {'UNDO', 'INTERNAL'}
data_path = rna_path_prop
value = StringProperty(name="Value",
@@ -227,7 +227,7 @@ class WM_OT_context_toggle(bpy.types.Operator):
'''Toggle a context value.'''
bl_idname = "wm.context_toggle"
bl_label = "Context Toggle"
- bl_options = {'UNDO'}
+ bl_options = {'UNDO', 'INTERNAL'}
data_path = rna_path_prop
@@ -246,7 +246,7 @@ class WM_OT_context_toggle_enum(bpy.types.Operator):
'''Toggle a context value.'''
bl_idname = "wm.context_toggle_enum"
bl_label = "Context Toggle Values"
- bl_options = {'UNDO'}
+ bl_options = {'UNDO', 'INTERNAL'}
data_path = rna_path_prop
value_1 = StringProperty(name="Value", \
@@ -273,7 +273,7 @@ class WM_OT_context_cycle_int(bpy.types.Operator):
'''vertex keys, groups' etc.'''
bl_idname = "wm.context_cycle_int"
bl_label = "Context Int Cycle"
- bl_options = {'UNDO'}
+ bl_options = {'UNDO', 'INTERNAL'}
data_path = rna_path_prop
reverse = rna_reverse_prop
@@ -307,7 +307,7 @@ class WM_OT_context_cycle_enum(bpy.types.Operator):
'''Toggle a context value.'''
bl_idname = "wm.context_cycle_enum"
bl_label = "Context Enum Cycle"
- bl_options = {'UNDO'}
+ bl_options = {'UNDO', 'INTERNAL'}
data_path = rna_path_prop
reverse = rna_reverse_prop
@@ -360,7 +360,7 @@ class WM_OT_context_cycle_array(bpy.types.Operator):
Useful for cycling the active mesh edit mode.'''
bl_idname = "wm.context_cycle_array"
bl_label = "Context Array Cycle"
- bl_options = {'UNDO'}
+ bl_options = {'UNDO', 'INTERNAL'}
data_path = rna_path_prop
reverse = rna_reverse_prop
@@ -406,7 +406,7 @@ class WM_MT_context_menu_enum(bpy.types.Menu):
class WM_OT_context_menu_enum(bpy.types.Operator):
bl_idname = "wm.context_menu_enum"
bl_label = "Context Enum Menu"
- bl_options = {'UNDO'}
+ bl_options = {'UNDO', 'INTERNAL'}
data_path = rna_path_prop
def execute(self, context):
@@ -420,7 +420,7 @@ class WM_OT_context_set_id(bpy.types.Operator):
'''Toggle a context value.'''
bl_idname = "wm.context_set_id"
bl_label = "Set Library ID"
- bl_options = {'UNDO'}
+ bl_options = {'UNDO', 'INTERNAL'}
data_path = rna_path_prop
value = StringProperty(name="Value",
@@ -462,6 +462,7 @@ class WM_OT_context_modal_mouse(bpy.types.Operator):
'''Adjust arbitrary values with mouse input'''
bl_idname = "wm.context_modal_mouse"
bl_label = "Context Modal Mouse"
+ bl_options = {'INTERNAL'}
data_path_iter = StringProperty(description="The data path relative to the context, must point to an iterable.")
data_path_item = StringProperty(description="The data path from each iterable to the value (int or float)")
diff --git a/release/scripts/startup/bl_ui/properties_data_curve.py b/release/scripts/startup/bl_ui/properties_data_curve.py
index 623daffac93..11a129377e8 100644
--- a/release/scripts/startup/bl_ui/properties_data_curve.py
+++ b/release/scripts/startup/bl_ui/properties_data_curve.py
@@ -116,6 +116,10 @@ class DATA_PT_shape_curve(CurveButtonsPanel, bpy.types.Panel):
col.label(text="Textures:")
col.prop(curve, "use_uv_as_generated")
col.prop(curve, "use_auto_texspace")
+
+ row = layout.row()
+ row.column().prop(curve, "texspace_location")
+ row.column().prop(curve, "texspace_size")
class DATA_PT_geometry_curve(CurveButtonsPanel, bpy.types.Panel):
diff --git a/release/scripts/startup/bl_ui/properties_data_mesh.py b/release/scripts/startup/bl_ui/properties_data_mesh.py
index 7097988d25b..e2c88413177 100644
--- a/release/scripts/startup/bl_ui/properties_data_mesh.py
+++ b/release/scripts/startup/bl_ui/properties_data_mesh.py
@@ -99,8 +99,9 @@ class DATA_PT_normals(MeshButtonsPanel, bpy.types.Panel):
split.prop(mesh, "show_double_sided")
-class DATA_PT_settings(MeshButtonsPanel, bpy.types.Panel):
- bl_label = "Settings"
+class DATA_PT_texture_space(MeshButtonsPanel, bpy.types.Panel):
+ bl_label = "Texture Space"
+ bl_options = {'DEFAULT_CLOSED'}
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
def draw(self, context):
@@ -109,8 +110,13 @@ class DATA_PT_settings(MeshButtonsPanel, bpy.types.Panel):
mesh = context.mesh
layout.prop(mesh, "texture_mesh")
- layout.prop(mesh, "use_auto_texspace")
+ layout.separator()
+
+ layout.prop(mesh, "use_auto_texspace")
+ row = layout.row()
+ row.column().prop(mesh, "texspace_location", text="Location")
+ row.column().prop(mesh, "texspace_size", text="Size")
class DATA_PT_vertex_groups(MeshButtonsPanel, bpy.types.Panel):
bl_label = "Vertex Groups"
diff --git a/release/scripts/startup/bl_ui/properties_data_metaball.py b/release/scripts/startup/bl_ui/properties_data_metaball.py
index 81ba15d6f40..c568d10b3b0 100644
--- a/release/scripts/startup/bl_ui/properties_data_metaball.py
+++ b/release/scripts/startup/bl_ui/properties_data_metaball.py
@@ -70,6 +70,10 @@ class DATA_PT_metaball(DataButtonsPanel, bpy.types.Panel):
layout.label(text="Update:")
layout.prop(mball, "update_method", expand=True)
+
+ row = layout.row()
+ row.column().prop(mball, "texspace_location")
+ row.column().prop(mball, "texspace_size")
class DATA_PT_metaball_element(DataButtonsPanel, bpy.types.Panel):
diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py
index 75069993521..586675f2ca0 100644
--- a/release/scripts/startup/bl_ui/properties_data_modifier.py
+++ b/release/scripts/startup/bl_ui/properties_data_modifier.py
@@ -483,11 +483,10 @@ class DATA_PT_modifiers(ModifierButtonsPanel, bpy.types.Panel):
col.label(text="Mode:")
col.prop(md, "wrap_method", text="")
- split = layout.split(percentage=0.25)
-
- col = split.column()
-
if md.wrap_method == 'PROJECT':
+ split = layout.split(percentage=0.25)
+
+ col = split.column()
col.label(text="Axis:")
col.prop(md, "use_project_x")
col.prop(md, "use_project_y")
@@ -499,7 +498,6 @@ class DATA_PT_modifiers(ModifierButtonsPanel, bpy.types.Panel):
col.prop(md, "use_positive_direction")
col = split.column()
-
col.label(text="Cull Faces:")
col.prop(md, "cull_face", expand=True)
diff --git a/release/scripts/startup/bl_ui/properties_object_constraint.py b/release/scripts/startup/bl_ui/properties_object_constraint.py
index 70121a12caa..8e175244216 100644
--- a/release/scripts/startup/bl_ui/properties_object_constraint.py
+++ b/release/scripts/startup/bl_ui/properties_object_constraint.py
@@ -660,17 +660,19 @@ class ConstraintButtonsPanel():
row = col.row()
row.label(text="Source to Destination Mapping:")
+ # note: chr(187) is the ASCII arrow ( >> ). Blender Text Editor can't
+ # open it. Thus we are using the hardcoded value instead.
row = col.row()
row.prop(con, "map_to_x_from", expand=False, text="")
- row.label(text=" -> X")
+ row.label(text=" %s X" % chr(187))
row = col.row()
row.prop(con, "map_to_y_from", expand=False, text="")
- row.label(text=" -> Y")
+ row.label(text=" %s Y" % chr(187))
row = col.row()
row.prop(con, "map_to_z_from", expand=False, text="")
- row.label(text=" -> Z")
+ row.label(text=" %s Z" % chr(187))
split = layout.split()
diff --git a/release/scripts/startup/bl_ui/properties_physics_fluid.py b/release/scripts/startup/bl_ui/properties_physics_fluid.py
index 5da89d0090a..c7e3a9e7220 100644
--- a/release/scripts/startup/bl_ui/properties_physics_fluid.py
+++ b/release/scripts/startup/bl_ui/properties_physics_fluid.py
@@ -257,6 +257,7 @@ class PHYSICS_PT_domain_boundary(PhysicButtonsPanel, bpy.types.Panel):
col.prop(fluid, "slip_type", text="")
if fluid.slip_type == 'PARTIALSLIP':
col.prop(fluid, "partial_slip_factor", slider=True, text="Amount")
+ col.prop(fluid, "surface_noobs")
col = split.column()
col.label(text="Surface:")
diff --git a/release/scripts/startup/bl_ui/properties_render.py b/release/scripts/startup/bl_ui/properties_render.py
index a3b10702fa7..54ca18ef828 100644
--- a/release/scripts/startup/bl_ui/properties_render.py
+++ b/release/scripts/startup/bl_ui/properties_render.py
@@ -172,8 +172,130 @@ class RENDER_PT_layers(RenderButtonsPanel, bpy.types.Panel):
row.prop(rl, "exclude_refraction", text="")
+class RENDER_PT_dimensions(RenderButtonsPanel, bpy.types.Panel):
+ bl_label = "Dimensions"
+ COMPAT_ENGINES = {'BLENDER_RENDER'}
+
+ def draw(self, context):
+ layout = self.layout
+
+ scene = context.scene
+ rd = scene.render
+
+ row = layout.row(align=True)
+ row.menu("RENDER_MT_presets", text=bpy.types.RENDER_MT_presets.bl_label)
+ row.operator("render.preset_add", text="", icon="ZOOMIN")
+ row.operator("render.preset_add", text="", icon="ZOOMOUT").remove_active = True
+
+ split = layout.split()
+
+ col = split.column()
+ sub = col.column(align=True)
+ sub.label(text="Resolution:")
+ sub.prop(rd, "resolution_x", text="X")
+ sub.prop(rd, "resolution_y", text="Y")
+ sub.prop(rd, "resolution_percentage", text="")
+
+ sub.label(text="Aspect Ratio:")
+ sub.prop(rd, "pixel_aspect_x", text="X")
+ sub.prop(rd, "pixel_aspect_y", text="Y")
+
+ row = col.row()
+ row.prop(rd, "use_border", text="Border")
+ sub = row.row()
+ sub.active = rd.use_border
+ sub.prop(rd, "use_crop_to_border", text="Crop")
+
+ col = split.column()
+ sub = col.column(align=True)
+ sub.label(text="Frame Range:")
+ sub.prop(scene, "frame_start", text="Start")
+ sub.prop(scene, "frame_end", text="End")
+ sub.prop(scene, "frame_step", text="Step")
+
+ sub.label(text="Frame Rate:")
+ if rd.fps_base == 1:
+ fps_rate = round(rd.fps / rd.fps_base)
+ else:
+ fps_rate = round(rd.fps / rd.fps_base, 2)
+
+ # TODO: Change the following to iterate over existing presets
+ custom_framerate = (fps_rate not in {23.98, 24, 25, 29.97, 30, 50, 59.94, 60})
+
+ if custom_framerate == True:
+ fps_label_text = "Custom (" + str(fps_rate) + " fps)"
+ else:
+ fps_label_text = str(fps_rate) + " fps"
+
+ sub.menu("RENDER_MT_framerate_presets", text=fps_label_text)
+
+ if custom_framerate or (bpy.types.RENDER_MT_framerate_presets.bl_label == "Custom"):
+ sub.prop(rd, "fps")
+ sub.prop(rd, "fps_base", text="/")
+ subrow = sub.row(align=True)
+ subrow.label(text="Time Remapping:")
+ subrow = sub.row(align=True)
+ subrow.prop(rd, "frame_map_old", text="Old")
+ subrow.prop(rd, "frame_map_new", text="New")
+
+
+class RENDER_PT_antialiasing(RenderButtonsPanel, bpy.types.Panel):
+ bl_label = "Anti-Aliasing"
+ COMPAT_ENGINES = {'BLENDER_RENDER'}
+
+ def draw_header(self, context):
+ rd = context.scene.render
+
+ self.layout.prop(rd, "use_antialiasing", text="")
+
+ def draw(self, context):
+ layout = self.layout
+
+ rd = context.scene.render
+ layout.active = rd.use_antialiasing
+
+ split = layout.split()
+
+ col = split.column()
+ col.row().prop(rd, "antialiasing_samples", expand=True)
+ sub = col.row()
+ sub.enabled = not rd.use_border
+ sub.prop(rd, "use_full_sample")
+
+ col = split.column()
+ col.prop(rd, "pixel_filter_type", text="")
+ col.prop(rd, "filter_size", text="Size")
+
+
+class RENDER_PT_motion_blur(RenderButtonsPanel, bpy.types.Panel):
+ bl_label = "Sampled Motion Blur"
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'BLENDER_RENDER'}
+
+ @classmethod
+ def poll(cls, context):
+ rd = context.scene.render
+ return not rd.use_full_sample and (rd.engine in cls.COMPAT_ENGINES)
+
+ def draw_header(self, context):
+ rd = context.scene.render
+
+ self.layout.prop(rd, "use_motion_blur", text="")
+
+ def draw(self, context):
+ layout = self.layout
+
+ rd = context.scene.render
+ layout.active = rd.use_motion_blur
+
+ row = layout.row()
+ row.prop(rd, "motion_blur_samples")
+ row.prop(rd, "motion_blur_shutter")
+
+
class RENDER_PT_shading(RenderButtonsPanel, bpy.types.Panel):
bl_label = "Shading"
+ bl_options = {'DEFAULT_CLOSED'}
COMPAT_ENGINES = {'BLENDER_RENDER'}
def draw(self, context):
@@ -254,8 +376,7 @@ class RENDER_PT_post_processing(RenderButtonsPanel, bpy.types.Panel):
col.prop(rd, "use_compositing")
col.prop(rd, "use_sequencer")
- col = split.column()
- col.prop(rd, "dither_intensity", text="Dither", slider=True)
+ split.prop(rd, "dither_intensity", text="Dither", slider=True)
layout.separator()
@@ -276,6 +397,51 @@ class RENDER_PT_post_processing(RenderButtonsPanel, bpy.types.Panel):
sub.prop(rd, "edge_color", text="")
+class RENDER_PT_stamp(RenderButtonsPanel, bpy.types.Panel):
+ bl_label = "Stamp"
+ bl_options = {'DEFAULT_CLOSED'}
+ COMPAT_ENGINES = {'BLENDER_RENDER'}
+
+ def draw_header(self, context):
+ rd = context.scene.render
+
+ self.layout.prop(rd, "use_stamp", text="")
+
+ def draw(self, context):
+ layout = self.layout
+
+ rd = context.scene.render
+
+ layout.active = rd.use_stamp
+
+ split = layout.split()
+
+ col = split.column()
+ col.prop(rd, "use_stamp_time", text="Time")
+ col.prop(rd, "use_stamp_date", text="Date")
+ 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.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()
+ sub.active = rd.use_stamp_note
+ sub.prop(rd, "stamp_note_text", text="")
+
+
class RENDER_PT_output(RenderButtonsPanel, bpy.types.Panel):
bl_label = "Output"
COMPAT_ENGINES = {'BLENDER_RENDER'}
@@ -433,172 +599,6 @@ class RENDER_PT_encoding(RenderButtonsPanel, bpy.types.Panel):
split.prop(rd, "ffmpeg_audio_volume", slider=True)
-class RENDER_PT_antialiasing(RenderButtonsPanel, bpy.types.Panel):
- bl_label = "Anti-Aliasing"
- COMPAT_ENGINES = {'BLENDER_RENDER'}
-
- def draw_header(self, context):
- rd = context.scene.render
-
- self.layout.prop(rd, "use_antialiasing", text="")
-
- def draw(self, context):
- layout = self.layout
-
- rd = context.scene.render
- layout.active = rd.use_antialiasing
-
- split = layout.split()
-
- col = split.column()
- col.row().prop(rd, "antialiasing_samples", expand=True)
- sub = col.row()
- sub.enabled = not rd.use_border
- sub.prop(rd, "use_full_sample")
-
- col = split.column()
- col.prop(rd, "pixel_filter_type", text="")
- col.prop(rd, "filter_size", text="Size")
-
-
-class RENDER_PT_motion_blur(RenderButtonsPanel, bpy.types.Panel):
- bl_label = "Sampled Motion Blur"
- bl_options = {'DEFAULT_CLOSED'}
- COMPAT_ENGINES = {'BLENDER_RENDER'}
-
- @classmethod
- def poll(cls, context):
- rd = context.scene.render
- return not rd.use_full_sample and (rd.engine in cls.COMPAT_ENGINES)
-
- def draw_header(self, context):
- rd = context.scene.render
-
- self.layout.prop(rd, "use_motion_blur", text="")
-
- def draw(self, context):
- layout = self.layout
-
- rd = context.scene.render
- layout.active = rd.use_motion_blur
-
- row = layout.row()
- row.prop(rd, "motion_blur_samples")
- row.prop(rd, "motion_blur_shutter")
-
-
-class RENDER_PT_dimensions(RenderButtonsPanel, bpy.types.Panel):
- bl_label = "Dimensions"
- COMPAT_ENGINES = {'BLENDER_RENDER'}
-
- def draw(self, context):
- layout = self.layout
-
- scene = context.scene
- rd = scene.render
-
- row = layout.row(align=True)
- row.menu("RENDER_MT_presets", text=bpy.types.RENDER_MT_presets.bl_label)
- row.operator("render.preset_add", text="", icon="ZOOMIN")
- row.operator("render.preset_add", text="", icon="ZOOMOUT").remove_active = True
-
- split = layout.split()
-
- col = split.column()
- sub = col.column(align=True)
- sub.label(text="Resolution:")
- sub.prop(rd, "resolution_x", text="X")
- sub.prop(rd, "resolution_y", text="Y")
- sub.prop(rd, "resolution_percentage", text="")
-
- sub.label(text="Aspect Ratio:")
- sub.prop(rd, "pixel_aspect_x", text="X")
- sub.prop(rd, "pixel_aspect_y", text="Y")
-
- row = col.row()
- row.prop(rd, "use_border", text="Border")
- sub = row.row()
- sub.active = rd.use_border
- sub.prop(rd, "use_crop_to_border", text="Crop")
-
- col = split.column()
- sub = col.column(align=True)
- sub.label(text="Frame Range:")
- sub.prop(scene, "frame_start", text="Start")
- sub.prop(scene, "frame_end", text="End")
- sub.prop(scene, "frame_step", text="Step")
-
- sub.label(text="Frame Rate:")
- if rd.fps_base == 1:
- fps_rate = round(rd.fps / rd.fps_base)
- else:
- fps_rate = round(rd.fps / rd.fps_base, 2)
-
- # TODO: Change the following to iterate over existing presets
- custom_framerate = (fps_rate not in {23.98, 24, 25, 29.97, 30, 50, 59.94, 60})
-
- if custom_framerate == True:
- fps_label_text = "Custom (" + str(fps_rate) + " fps)"
- else:
- fps_label_text = str(fps_rate) + " fps"
-
- sub.menu("RENDER_MT_framerate_presets", text=fps_label_text)
-
- if custom_framerate or (bpy.types.RENDER_MT_framerate_presets.bl_label == "Custom"):
- sub.prop(rd, "fps")
- sub.prop(rd, "fps_base", text="/")
- subrow = sub.row(align=True)
- subrow.label(text="Time Remapping:")
- subrow = sub.row(align=True)
- subrow.prop(rd, "frame_map_old", text="Old")
- subrow.prop(rd, "frame_map_new", text="New")
-
-
-class RENDER_PT_stamp(RenderButtonsPanel, bpy.types.Panel):
- bl_label = "Stamp"
- bl_options = {'DEFAULT_CLOSED'}
- COMPAT_ENGINES = {'BLENDER_RENDER'}
-
- def draw_header(self, context):
- rd = context.scene.render
-
- self.layout.prop(rd, "use_stamp", text="")
-
- def draw(self, context):
- layout = self.layout
-
- rd = context.scene.render
-
- layout.active = rd.use_stamp
-
- split = layout.split()
-
- col = split.column()
- col.prop(rd, "use_stamp_time", text="Time")
- col.prop(rd, "use_stamp_date", text="Date")
- 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.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()
- sub.active = rd.use_stamp_note
- sub.prop(rd, "stamp_note_text", text="")
-
-
class RENDER_PT_bake(RenderButtonsPanel, bpy.types.Panel):
bl_label = "Bake"
bl_options = {'DEFAULT_CLOSED'}
@@ -613,29 +613,42 @@ class RENDER_PT_bake(RenderButtonsPanel, bpy.types.Panel):
layout.prop(rd, "bake_type")
- if rd.bake_type == 'NORMALS':
- layout.prop(rd, "bake_normal_space")
- elif rd.bake_type in {'DISPLACEMENT', 'AO'}:
- layout.prop(rd, "use_bake_normalize")
+ multires_bake = False
+ if rd.bake_type in ['NORMALS', 'DISPLACEMENT']:
+ layout.prop(rd, 'use_bake_multires')
+ multires_bake = rd.use_bake_multires
- # col.prop(rd, "bake_aa_mode")
- # col.prop(rd, "use_bake_antialiasing")
+ if not multires_bake:
+ if rd.bake_type == 'NORMALS':
+ layout.prop(rd, "bake_normal_space")
+ elif rd.bake_type in {'DISPLACEMENT', 'AO'}:
+ layout.prop(rd, "use_bake_normalize")
- layout.separator()
+ # col.prop(rd, "bake_aa_mode")
+ # col.prop(rd, "use_bake_antialiasing")
- split = layout.split()
+ layout.separator()
- col = split.column()
- col.prop(rd, "use_bake_clear")
- col.prop(rd, "bake_margin")
- col.prop(rd, "bake_quad_split", text="Split")
+ split = layout.split()
+
+ col = split.column()
+ col.prop(rd, "use_bake_clear")
+ col.prop(rd, "bake_margin")
+ col.prop(rd, "bake_quad_split", text="Split")
+
+ col = split.column()
+ col.prop(rd, "use_bake_selected_to_active")
+ sub = col.column()
+ sub.active = rd.use_bake_selected_to_active
+ sub.prop(rd, "bake_distance")
+ sub.prop(rd, "bake_bias")
+ else:
+ if rd.bake_type == 'DISPLACEMENT':
+ layout.prop(rd, "use_bake_lores_mesh")
+
+ layout.prop(rd, "use_bake_clear")
+ layout.prop(rd, "bake_margin")
- col = split.column()
- col.prop(rd, "use_bake_selected_to_active")
- sub = col.column()
- sub.active = rd.use_bake_selected_to_active
- sub.prop(rd, "bake_distance")
- sub.prop(rd, "bake_bias")
if __name__ == "__main__": # only for live edit.
bpy.utils.register_module(__name__)
diff --git a/release/scripts/startup/bl_ui/space_sequencer.py b/release/scripts/startup/bl_ui/space_sequencer.py
index 858c619d3c1..c477a2ff62b 100644
--- a/release/scripts/startup/bl_ui/space_sequencer.py
+++ b/release/scripts/startup/bl_ui/space_sequencer.py
@@ -42,7 +42,7 @@ class SEQUENCER_HT_header(bpy.types.Header):
sub = row.row(align=True)
sub.menu("SEQUENCER_MT_view")
- if (st.view_type == 'SEQUENCER') or (st.view_type == 'SEQUENCER_PREVIEW'):
+ if st.view_type in {'SEQUENCER', 'SEQUENCER_PREVIEW'}:
sub.menu("SEQUENCER_MT_select")
sub.menu("SEQUENCER_MT_marker")
sub.menu("SEQUENCER_MT_add")
@@ -50,17 +50,17 @@ class SEQUENCER_HT_header(bpy.types.Header):
layout.prop(st, "view_type", expand=True, text="")
- if (st.view_type == 'PREVIEW') or (st.view_type == 'SEQUENCER_PREVIEW'):
+ if st.view_type in {'PREVIEW', 'SEQUENCER_PREVIEW'}:
layout.prop(st, "display_mode", expand=True, text="")
- if (st.view_type == 'SEQUENCER'):
+ if st.view_type == 'SEQUENCER':
row = layout.row(align=True)
row.operator("sequencer.copy", text="", icon='COPYDOWN')
row.operator("sequencer.paste", text="", icon='PASTEDOWN')
layout.separator()
layout.operator("sequencer.refresh_all")
- elif (st.view_type == 'SEQUENCER_PREVIEW'):
+ elif st.view_type == 'SEQUENCER_PREVIEW':
layout.separator()
layout.operator("sequencer.refresh_all")
layout.prop(st, "display_channel", text="Channel")
@@ -101,9 +101,9 @@ class SEQUENCER_MT_view(bpy.types.Menu):
layout.separator()
- if (st.view_type == 'SEQUENCER') or (st.view_type == 'SEQUENCER_PREVIEW'):
+ if st.view_type in {'SEQUENCER', 'SEQUENCER_PREVIEW'}:
layout.operator("sequencer.view_all", text='View all Sequences')
- if (st.view_type == 'PREVIEW') or (st.view_type == 'SEQUENCER_PREVIEW'):
+ if st.view_type in {'PREVIEW', 'SEQUENCER_PREVIEW'}:
layout.operator_context = 'INVOKE_REGION_PREVIEW'
layout.operator("sequencer.view_all_preview", text='Fit preview in window')
layout.operator("sequencer.view_zoom_ratio", text='Show preview 1:1').ratio = 1.0
@@ -300,7 +300,7 @@ class SequencerButtonsPanel():
@staticmethod
def has_sequencer(context):
- return (context.space_data.view_type == 'SEQUENCER') or (context.space_data.view_type == 'SEQUENCER_PREVIEW')
+ return (context.space_data.view_type in {'SEQUENCER', 'SEQUENCER_PREVIEW'})
@classmethod
def poll(cls, context):
@@ -313,7 +313,7 @@ class SequencerButtonsPanel_Output():
@staticmethod
def has_preview(context):
- return (context.space_data.view_type == 'PREVIEW') or (context.space_data.view_type == 'SEQUENCER_PREVIEW')
+ return (context.space_data.view_type in {'PREVIEW', 'SEQUENCER_PREVIEW'})
@classmethod
def poll(cls, context):
@@ -657,11 +657,17 @@ class SEQUENCER_PT_scene(SequencerButtonsPanel, bpy.types.Panel):
layout.template_ID(strip, "scene")
+ scene = strip.scene
+ if scene:
+ layout.prop(scene.render, "use_sequencer")
+
layout.label(text="Camera Override")
layout.template_ID(strip, "scene_camera")
- sce = strip.scene
- layout.label(text="Original frame range: %d-%d (%d)" % (sce.frame_start, sce.frame_end, sce.frame_end - sce.frame_start + 1))
+ if scene:
+ sta = scene.frame_start
+ end = scene.frame_end
+ layout.label(text="Original frame range: %d-%d (%d)" % (sta, end, end - sta + 1))
class SEQUENCER_PT_filter(SequencerButtonsPanel, bpy.types.Panel):
diff --git a/release/scripts/startup/bl_ui/space_text.py b/release/scripts/startup/bl_ui/space_text.py
index 5b07e8dc37f..0fc8d937f66 100644
--- a/release/scripts/startup/bl_ui/space_text.py
+++ b/release/scripts/startup/bl_ui/space_text.py
@@ -42,7 +42,7 @@ class TEXT_HT_header(bpy.types.Header):
if text and text.is_modified:
row = layout.row()
- # row.color(redalert)
+ row.alert = True
row.operator("text.resolve_conflict", text="", icon='HELP')
layout.template_ID(st, "text", new="text.new", unlink="text.unlink")
diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py
index 24d54a83334..222f2735a3e 100644
--- a/release/scripts/startup/bl_ui/space_userpref.py
+++ b/release/scripts/startup/bl_ui/space_userpref.py
@@ -94,7 +94,7 @@ class USERPREF_HT_header(bpy.types.Header):
layout.operator("wm.keyconfig_import")
elif userpref.active_section == 'ADDONS':
layout.operator("wm.addon_install")
- layout.menu("USERPREF_MT_addons_dev_guides", text=" Addons Developer Guides", icon='INFO')
+ layout.menu("USERPREF_MT_addons_dev_guides")
elif userpref.active_section == 'THEMES':
layout.operator("ui.reset_default_theme")
@@ -848,17 +848,14 @@ class USERPREF_PT_input(bpy.types.Panel, InputKeyMapPanel):
class USERPREF_MT_addons_dev_guides(bpy.types.Menu):
- bl_label = "Addons develoment guides"
+ bl_label = "Develoment Guides"
# menu to open webpages with addons development guides
def draw(self, context):
layout = self.layout
- layout.operator('wm.url_open', text='API Concepts'
- ).url = 'http://wiki.blender.org/index.php/Dev:2.5/Py/API/Intro'
- layout.operator('wm.url_open', text='Addons guidelines',
- ).url = 'http://wiki.blender.org/index.php/Dev:2.5/Py/Scripts/Guidelines/Addons'
- layout.operator('wm.url_open', text='How to share your addon',
- ).url = 'http://wiki.blender.org/index.php/Dev:Py/Sharing'
+ layout.operator('wm.url_open', text='API Concepts', icon='URL').url = 'http://wiki.blender.org/index.php/Dev:2.5/Py/API/Intro'
+ layout.operator('wm.url_open', text='Addon Guidelines', icon='URL').url = 'http://wiki.blender.org/index.php/Dev:2.5/Py/Scripts/Guidelines/Addons'
+ layout.operator('wm.url_open', text='How to share your addon', icon='URL').url = 'http://wiki.blender.org/index.php/Dev:Py/Sharing'
class USERPREF_PT_addons(bpy.types.Panel):
diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index 3ea5480a99e..6d1caa5111d 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -689,6 +689,7 @@ class VIEW3D_MT_object(bpy.types.Menu):
layout.operator("ed.undo")
layout.operator("ed.redo")
+ layout.operator("ed.undo_history")
layout.separator()
@@ -1053,6 +1054,7 @@ class VIEW3D_MT_paint_weight(bpy.types.Menu):
layout.operator("ed.undo")
layout.operator("ed.redo")
+ layout.operator("ed.undo_history")
layout.separator()
@@ -1133,6 +1135,7 @@ class VIEW3D_MT_particle(bpy.types.Menu):
layout.operator("ed.undo")
layout.operator("ed.redo")
+ layout.operator("ed.undo_history")
layout.separator()
@@ -1186,6 +1189,7 @@ class VIEW3D_MT_pose(bpy.types.Menu):
layout.operator("ed.undo")
layout.operator("ed.redo")
+ layout.operator("ed.undo_history")
layout.separator()
@@ -1377,6 +1381,7 @@ class VIEW3D_MT_edit_mesh(bpy.types.Menu):
layout.operator("ed.undo")
layout.operator("ed.redo")
+ layout.operator("ed.undo_history")
layout.separator()
@@ -1848,6 +1853,7 @@ class VIEW3D_MT_edit_meta(bpy.types.Menu):
layout.operator("ed.undo")
layout.operator("ed.redo")
+ layout.operator("ed.undo_history")
layout.separator()
diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h
index a45e9a17dc9..07f0885372a 100644
--- a/source/blender/blenkernel/BKE_blender.h
+++ b/source/blender/blenkernel/BKE_blender.h
@@ -89,6 +89,7 @@ extern int BKE_undo_valid(const char *name);
extern void BKE_reset_undo(void);
extern char *BKE_undo_menu_string(void);
extern void BKE_undo_number(struct bContext *C, int nr);
+extern char *BKE_undo_get_name(int nr, int *active);
extern void BKE_undo_save_quit(void);
extern struct Main *BKE_undo_get_main(struct Scene **scene);
diff --git a/source/blender/blenkernel/BKE_brush.h b/source/blender/blenkernel/BKE_brush.h
index ad736cd07bf..ebb9714cd1b 100644
--- a/source/blender/blenkernel/BKE_brush.h
+++ b/source/blender/blenkernel/BKE_brush.h
@@ -71,7 +71,7 @@ float brush_curve_strength(struct Brush *br, float p, const float len); /* used
/* sampling */
void brush_sample_tex(struct Brush *brush, float *xy, float *rgba, const int thread);
void brush_imbuf_new(struct Brush *brush, short flt, short texfalloff, int size,
- struct ImBuf **imbuf);
+ struct ImBuf **imbuf, int use_color_correction);
/* painting */
struct BrushPainter;
@@ -82,7 +82,7 @@ BrushPainter *brush_painter_new(struct Brush *brush);
void brush_painter_require_imbuf(BrushPainter *painter, short flt,
short texonly, int size);
int brush_painter_paint(BrushPainter *painter, BrushFunc func, float *pos,
- double time, float pressure, void *user);
+ double time, float pressure, void *user, int use_color_correction);
void brush_painter_break_stroke(BrushPainter *painter);
void brush_painter_free(BrushPainter *painter);
diff --git a/source/blender/blenkernel/BKE_deform.h b/source/blender/blenkernel/BKE_deform.h
index a9ac201beda..64cea929573 100644
--- a/source/blender/blenkernel/BKE_deform.h
+++ b/source/blender/blenkernel/BKE_deform.h
@@ -59,9 +59,9 @@ float defvert_array_find_weight_safe(const struct MDeformVert *dvert, int index
void defvert_copy(struct MDeformVert *dvert_r, const struct MDeformVert *dvert);
void defvert_sync(struct MDeformVert *dvert_r, const struct MDeformVert *dvert, int use_verify);
-void defvert_sync_mapped(struct MDeformVert *dvert_r, const struct MDeformVert *dvert, int *flip_map, int use_verify);
+void defvert_sync_mapped(struct MDeformVert *dvert_r, const struct MDeformVert *dvert, const int *flip_map, int use_verify);
void defvert_remap (struct MDeformVert *dvert, int *map);
-void defvert_flip(struct MDeformVert *dvert, int *flip_map);
+void defvert_flip(struct MDeformVert *dvert, const int *flip_map);
void defvert_normalize(struct MDeformVert *dvert);
/* utility function, note that 32 chars is the maximum string length since its only
diff --git a/source/blender/blenkernel/BKE_depsgraph.h b/source/blender/blenkernel/BKE_depsgraph.h
index 14251fb1762..f36073ba841 100644
--- a/source/blender/blenkernel/BKE_depsgraph.h
+++ b/source/blender/blenkernel/BKE_depsgraph.h
@@ -51,22 +51,23 @@ struct GHash;
/* **** DAG relation types *** */
/* scene link to object */
-#define DAG_RL_SCENE 1
+#define DAG_RL_SCENE (1<<0)
/* object link to data */
-#define DAG_RL_DATA 2
+#define DAG_RL_DATA (1<<1)
/* object changes object (parent, track, constraints) */
-#define DAG_RL_OB_OB 4
+#define DAG_RL_OB_OB (1<<2)
/* object changes obdata (hooks, constraints) */
-#define DAG_RL_OB_DATA 8
+#define DAG_RL_OB_DATA (1<<3)
/* data changes object (vertex parent) */
-#define DAG_RL_DATA_OB 16
+#define DAG_RL_DATA_OB (1<<4)
/* data changes data (deformers) */
-#define DAG_RL_DATA_DATA 32
+#define DAG_RL_DATA_DATA (1<<5)
-#define DAG_NO_RELATION 64
-#define DAG_RL_ALL 63
-#define DAG_RL_ALL_BUT_DATA 61
+#define DAG_NO_RELATION (1<<6)
+
+#define DAG_RL_ALL_BUT_DATA (DAG_RL_SCENE|DAG_RL_OB_OB|DAG_RL_OB_DATA|DAG_RL_DATA_OB|DAG_RL_DATA_DATA)
+#define DAG_RL_ALL (DAG_RL_ALL_BUT_DATA|DAG_RL_DATA)
typedef void (*graph_action_func)(void * ob, void **data);
diff --git a/source/blender/blenkernel/BKE_multires.h b/source/blender/blenkernel/BKE_multires.h
index ea34ff4aa07..ba23b2d79c0 100644
--- a/source/blender/blenkernel/BKE_multires.h
+++ b/source/blender/blenkernel/BKE_multires.h
@@ -91,6 +91,7 @@ void multires_topology_changed(struct Scene *scene, struct Object *ob);
void old_mdisps_bilinear(float out[3], float (*disps)[3], const int st, float u, float v);
void mdisp_rot_crn_to_face(const int S, const int corners, const int face_side, const float x, const float y, float *u, float *v);
int mdisp_rot_face_to_crn(const int corners, const int face_side, const float u, const float v, float *x, float *y);
+int mdisp_rot_face_to_quad_crn(const int corners, const int face_side, const float u, const float v, float *x, float *y);
void mdisp_apply_weight(const int S, const int corners, int x, int y, const int face_side, float crn_weight[4][2], float *u_r, float *v_r);
void mdisp_flip_disp(const int S, const int corners, const float axis_x[2], const float axis_y[2], float disp[3]);
void mdisp_join_tris(struct MDisps *dst, struct MDisps *tri1, struct MDisps *tri2);
diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h
index 4dfc53e1734..feeab98ad78 100644
--- a/source/blender/blenkernel/BKE_particle.h
+++ b/source/blender/blenkernel/BKE_particle.h
@@ -300,6 +300,8 @@ void psys_get_pointcache_start_end(struct Scene *scene, ParticleSystem *psys, in
void psys_check_boid_data(struct ParticleSystem *psys);
+void psys_get_birth_coordinates(struct ParticleSimulationData *sim, struct ParticleData *pa, struct ParticleKey *state, float dtime, float cfra);
+
void particle_system_update(struct Scene *scene, struct Object *ob, struct ParticleSystem *psys);
/* ----------- functions needed only inside particlesystem ------------ */
diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c
index b852629e49c..5a9432552d2 100644
--- a/source/blender/blenkernel/intern/blender.c
+++ b/source/blender/blenkernel/intern/blender.c
@@ -180,7 +180,6 @@ static void clean_paths(Main *main)
BLI_bpathIterator_free(bpi);
for(scene= main->scene.first; scene; scene= scene->id.next) {
- BLI_clean(scene->r.backbuf);
BLI_clean(scene->r.pic);
}
}
@@ -620,7 +619,7 @@ void BKE_reset_undo(void)
/* based on index nr it does a restore */
void BKE_undo_number(bContext *C, int nr)
{
- curundo= BLI_findlink(&undobase, nr - 1);
+ curundo= BLI_findlink(&undobase, nr);
BKE_undo_step(C, 0);
}
@@ -646,6 +645,21 @@ int BKE_undo_valid(const char *name)
return undobase.last != undobase.first;
}
+/* get name of undo item, return null if no item with this index */
+/* if active pointer, set it to 1 if true */
+char *BKE_undo_get_name(int nr, int *active)
+{
+ UndoElem *uel= BLI_findlink(&undobase, nr);
+
+ if(active) *active= 0;
+
+ if(uel) {
+ if(active && uel==curundo)
+ *active= 1;
+ return uel->name;
+ }
+ return NULL;
+}
char *BKE_undo_menu_string(void)
{
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index 25b60fef6dd..a4ceb62ab55 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -521,7 +521,7 @@ void brush_sample_tex(Brush *brush, float *xy, float *rgba, const int thread)
}
-void brush_imbuf_new(Brush *brush, short flt, short texfall, int bufsize, ImBuf **outbuf)
+void brush_imbuf_new(Brush *brush, short flt, short texfall, int bufsize, ImBuf **outbuf, int use_color_correction)
{
ImBuf *ibuf;
float xy[2], dist, rgba[4], *dstf;
@@ -529,7 +529,8 @@ void brush_imbuf_new(Brush *brush, short flt, short texfall, int bufsize, ImBuf
const int radius= brush_size(brush);
char *dst, crgb[3];
const float alpha= brush_alpha(brush);
-
+ float brush_rgb[3];
+
imbflag= (flt)? IB_rectfloat: IB_rect;
xoff = -bufsize/2.0f + 0.5f;
yoff = -bufsize/2.0f + 0.5f;
@@ -541,6 +542,11 @@ void brush_imbuf_new(Brush *brush, short flt, short texfall, int bufsize, ImBuf
ibuf= IMB_allocImBuf(bufsize, bufsize, 32, imbflag);
if (flt) {
+ copy_v3_v3(brush_rgb, brush->rgb);
+ if(use_color_correction){
+ srgb_to_linearrgb_v3_v3(brush_rgb, brush_rgb);
+ }
+
for (y=0; y < ibuf->y; y++) {
dstf = ibuf->rect_float + y*rowbytes;
@@ -551,7 +557,7 @@ void brush_imbuf_new(Brush *brush, short flt, short texfall, int bufsize, ImBuf
if (texfall == 0) {
dist = sqrt(xy[0]*xy[0] + xy[1]*xy[1]);
- VECCOPY(dstf, brush->rgb);
+ VECCOPY(dstf, brush_rgb);
dstf[3]= alpha*brush_curve_strength_clamp(brush, dist, radius);
}
else if (texfall == 1) {
@@ -561,10 +567,7 @@ void brush_imbuf_new(Brush *brush, short flt, short texfall, int bufsize, ImBuf
dist = sqrt(xy[0]*xy[0] + xy[1]*xy[1]);
brush_sample_tex(brush, xy, rgba, 0);
-
- dstf[0] = rgba[0]*brush->rgb[0];
- dstf[1] = rgba[1]*brush->rgb[1];
- dstf[2] = rgba[2]*brush->rgb[2];
+ mul_v3_v3v3(dstf, rgba, brush_rgb);
dstf[3] = rgba[3]*alpha*brush_curve_strength_clamp(brush, dist, radius);
}
}
@@ -862,7 +865,7 @@ static void brush_painter_fixed_tex_partial_update(BrushPainter *painter, float
brush_painter_do_partial(painter, NULL, x1, y2, x2, ibuf->y, 0, 0, pos);
}
-static void brush_painter_refresh_cache(BrushPainter *painter, float *pos)
+static void brush_painter_refresh_cache(BrushPainter *painter, float *pos, int use_color_correction)
{
Brush *brush= painter->brush;
BrushPainterCache *cache= &painter->cache;
@@ -889,11 +892,11 @@ static void brush_painter_refresh_cache(BrushPainter *painter, float *pos)
size= (cache->size)? cache->size: diameter;
if (brush->flag & BRUSH_FIXED_TEX) {
- brush_imbuf_new(brush, flt, 3, size, &cache->maskibuf);
+ brush_imbuf_new(brush, flt, 3, size, &cache->maskibuf, use_color_correction);
brush_painter_fixed_tex_partial_update(painter, pos);
}
else
- brush_imbuf_new(brush, flt, 2, size, &cache->ibuf);
+ brush_imbuf_new(brush, flt, 2, size, &cache->ibuf, use_color_correction);
cache->lastsize= diameter;
cache->lastalpha= alpha;
@@ -952,7 +955,7 @@ void brush_jitter_pos(Brush *brush, float *pos, float *jitterpos)
}
}
-int brush_painter_paint(BrushPainter *painter, BrushFunc func, float *pos, double time, float pressure, void *user)
+int brush_painter_paint(BrushPainter *painter, BrushFunc func, float *pos, double time, float pressure, void *user, int use_color_correction)
{
Brush *brush= painter->brush;
int totpaintops= 0;
@@ -970,7 +973,7 @@ int brush_painter_paint(BrushPainter *painter, BrushFunc func, float *pos, doubl
brush_apply_pressure(painter, brush, pressure);
if (painter->cache.enabled)
- brush_painter_refresh_cache(painter, pos);
+ brush_painter_refresh_cache(painter, pos, use_color_correction);
totpaintops += func(user, painter->cache.ibuf, pos, pos);
painter->lasttime= time;
@@ -1043,7 +1046,7 @@ int brush_painter_paint(BrushPainter *painter, BrushFunc func, float *pos, doubl
brush_jitter_pos(brush, paintpos, finalpos);
if (painter->cache.enabled)
- brush_painter_refresh_cache(painter, finalpos);
+ brush_painter_refresh_cache(painter, finalpos, use_color_correction);
totpaintops +=
func(user, painter->cache.ibuf, painter->lastpaintpos, finalpos);
@@ -1057,7 +1060,7 @@ int brush_painter_paint(BrushPainter *painter, BrushFunc func, float *pos, doubl
brush_jitter_pos(brush, pos, finalpos);
if (painter->cache.enabled)
- brush_painter_refresh_cache(painter, finalpos);
+ brush_painter_refresh_cache(painter, finalpos, use_color_correction);
totpaintops += func(user, painter->cache.ibuf, pos, finalpos);
@@ -1085,7 +1088,7 @@ int brush_painter_paint(BrushPainter *painter, BrushFunc func, float *pos, doubl
brush_jitter_pos(brush, pos, finalpos);
if (painter->cache.enabled)
- brush_painter_refresh_cache(painter, finalpos);
+ brush_painter_refresh_cache(painter, finalpos, use_color_correction);
totpaintops +=
func(user, painter->cache.ibuf, painter->lastmousepos, finalpos);
diff --git a/source/blender/blenkernel/intern/bvhutils.c b/source/blender/blenkernel/intern/bvhutils.c
index 5520e4d1d41..cc45abb5998 100644
--- a/source/blender/blenkernel/intern/bvhutils.c
+++ b/source/blender/blenkernel/intern/bvhutils.c
@@ -493,7 +493,7 @@ static void mesh_edges_nearest_point(void *userdata, int index, const float *co,
// NOTE: casts to "float*" here are due to co being "const float*"
closest_to_line_segment_v3(nearest_tmp, (float*)co, t0, t1);
- dist = len_v3v3(nearest_tmp, (float*)co);
+ dist = len_squared_v3v3(nearest_tmp, (float*)co);
if(dist < nearest->dist)
{
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index f5f069767eb..45faba8439c 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -540,7 +540,7 @@ static void layerInterp_mdisps(void **sources, float *UNUSED(weights),
float face_u, face_v, crn_u, crn_v;
mdisp_apply_weight(S, dst_corners, x, y, st, crn_weight, &face_u, &face_v);
- crn = mdisp_rot_face_to_crn(src_corners, st, face_u, face_v, &crn_u, &crn_v);
+ crn = mdisp_rot_face_to_quad_crn(src_corners, st, face_u, face_v, &crn_u, &crn_v);
old_mdisps_bilinear((*out), &s->disps[crn*side*side], side, crn_u, crn_v);
mdisp_flip_disp(crn, dst_corners, axis_x, axis_y, *out);
diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c
index 0696653d2e4..11a0a5884ee 100644
--- a/source/blender/blenkernel/intern/deform.c
+++ b/source/blender/blenkernel/intern/deform.c
@@ -121,7 +121,7 @@ void defvert_sync (MDeformVert *dvert_r, const MDeformVert *dvert, int use_verif
}
/* be sure all flip_map values are valid */
-void defvert_sync_mapped (MDeformVert *dvert_r, const MDeformVert *dvert, int *flip_map, int use_verify)
+void defvert_sync_mapped (MDeformVert *dvert_r, const MDeformVert *dvert, const int *flip_map, int use_verify)
{
if(dvert->totweight && dvert_r->totweight) {
int i;
@@ -170,7 +170,7 @@ void defvert_normalize (MDeformVert *dvert)
}
}
-void defvert_flip (MDeformVert *dvert, int *flip_map)
+void defvert_flip (MDeformVert *dvert, const int *flip_map)
{
MDeformWeight *dw;
int i;
diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c
index 13ab89200db..d833c184274 100644
--- a/source/blender/blenkernel/intern/multires.c
+++ b/source/blender/blenkernel/intern/multires.c
@@ -1020,7 +1020,7 @@ static void old_mdisps_rotate(int S, int UNUSED(newside), int oldside, int x, in
static void old_mdisps_convert(MFace *mface, MDisps *mdisp)
{
- int newlvl = log(sqrt(mdisp->totdisp)-1)/log(2);
+ int newlvl = log(sqrt(mdisp->totdisp)-1)/M_LN2;
int oldlvl = newlvl+1;
int oldside = multires_side_tot[oldlvl];
int newside = multires_side_tot[newlvl];
@@ -1997,6 +1997,7 @@ void mdisp_rot_crn_to_face(const int S, const int corners, const int face_side,
}
}
+/* Find per-corner coordinate with given per-face UV coord */
int mdisp_rot_face_to_crn(const int corners, const int face_side, const float u, const float v, float *x, float *y)
{
const float offset = face_side*0.5f - 0.5f;
@@ -2022,6 +2023,61 @@ int mdisp_rot_face_to_crn(const int corners, const int face_side, const float u,
*y = v - offset;
}
} else {
+ int grid_size = offset;
+ float w = (face_side - 1) - u - v;
+ float W1, W2;
+
+ if (u >= v && u >= w) {S = 0; W1= w; W2= v;}
+ else if (v >= u && v >= w) {S = 1; W1 = u; W2 = w;}
+ else {S = 2; W1 = v; W2 = u;}
+
+ W1 /= (face_side-1);
+ W2 /= (face_side-1);
+
+ *x = (1-(2*W1)/(1-W2)) * grid_size;
+ *y = (1-(2*W2)/(1-W1)) * grid_size;
+ }
+
+ return S;
+}
+
+/* Find per-corner coordinate with given per-face UV coord
+ Practically as the previous funciton but it assumes a bit different coordinate system for triangles
+ which is optimized for MDISP layer interpolation:
+
+ v
+ ^
+ | /|
+ | / |
+ | / |
+ |/______|___> u
+
+ */
+int mdisp_rot_face_to_quad_crn(const int corners, const int face_side, const float u, const float v, float *x, float *y)
+{
+ const float offset = face_side*0.5f - 0.5f;
+ int S = 0;
+
+ if (corners == 4) {
+ if(u <= offset && v <= offset) S = 0;
+ else if(u > offset && v <= offset) S = 1;
+ else if(u > offset && v > offset) S = 2;
+ else if(u <= offset && v >= offset) S = 3;
+
+ if(S == 0) {
+ *y = offset - u;
+ *x = offset - v;
+ } else if(S == 1) {
+ *x = u - offset;
+ *y = offset - v;
+ } else if(S == 2) {
+ *y = u - offset;
+ *x = v - offset;
+ } else if(S == 3) {
+ *x= offset - u;
+ *y = v - offset;
+ }
+ } else {
float crn[3][4][2];
float p[2] = {u, v};
@@ -2148,7 +2204,7 @@ void mdisp_join_tris(MDisps *dst, MDisps *tri1, MDisps *tri2)
face_v = st - 1 - face_v;
} else src = tri1;
- crn = mdisp_rot_face_to_crn(3, st, face_u, face_v, &crn_u, &crn_v);
+ crn = mdisp_rot_face_to_quad_crn(3, st, face_u, face_v, &crn_u, &crn_v);
old_mdisps_bilinear((*out), &src->disps[crn*side*side], side, crn_u, crn_v);
(*out)[0] = 0;
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index d0fbc6247b5..16fa1605467 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -2387,24 +2387,42 @@ void object_set_dimensions(Object *ob, const float *value)
void minmax_object(Object *ob, float *min, float *max)
{
BoundBox bb;
- Mesh *me;
- Curve *cu;
float vec[3];
int a;
+ short change= FALSE;
switch(ob->type) {
-
case OB_CURVE:
case OB_FONT:
case OB_SURF:
- cu= ob->data;
-
- if(cu->bb==NULL) tex_space_curve(cu);
- bb= *(cu->bb);
-
- for(a=0; a<8; a++) {
- mul_m4_v3(ob->obmat, bb.vec[a]);
- DO_MINMAX(bb.vec[a], min, max);
+ {
+ Curve *cu= ob->data;
+
+ if(cu->bb==NULL) tex_space_curve(cu);
+ bb= *(cu->bb);
+
+ for(a=0; a<8; a++) {
+ mul_m4_v3(ob->obmat, bb.vec[a]);
+ DO_MINMAX(bb.vec[a], min, max);
+ }
+ change= TRUE;
+ }
+ break;
+ case OB_LATTICE:
+ {
+ Lattice *lt= ob->data;
+ BPoint *bp= lt->def;
+ int u, v, w;
+
+ for(w=0; w<lt->pntsw; w++) {
+ for(v=0; v<lt->pntsv; v++) {
+ for(u=0; u<lt->pntsu; u++, bp++) {
+ mul_v3_m4v3(vec, ob->obmat, bp->vec);
+ DO_MINMAX(vec, min, max);
+ }
+ }
+ }
+ change= TRUE;
}
break;
case OB_ARMATURE:
@@ -2416,25 +2434,27 @@ void minmax_object(Object *ob, float *min, float *max)
mul_v3_m4v3(vec, ob->obmat, pchan->pose_tail);
DO_MINMAX(vec, min, max);
}
- break;
+ change= TRUE;
}
- /* no break, get_mesh will give NULL and it passes on to default */
+ break;
case OB_MESH:
- me= get_mesh(ob);
-
- if(me) {
- bb = *mesh_get_bb(ob);
-
- for(a=0; a<8; a++) {
- mul_m4_v3(ob->obmat, bb.vec[a]);
- DO_MINMAX(bb.vec[a], min, max);
+ {
+ Mesh *me= get_mesh(ob);
+
+ if(me) {
+ bb = *mesh_get_bb(ob);
+
+ for(a=0; a<8; a++) {
+ mul_m4_v3(ob->obmat, bb.vec[a]);
+ DO_MINMAX(bb.vec[a], min, max);
+ }
+ change= TRUE;
}
}
- if(min[0] < max[0] ) break;
-
- /* else here no break!!!, mesh can be zero sized */
-
- default:
+ break;
+ }
+
+ if(change == FALSE) {
DO_MINMAX(ob->obmat[3], min, max);
copy_v3_v3(vec, ob->obmat[3]);
@@ -2444,7 +2464,6 @@ void minmax_object(Object *ob, float *min, float *max)
copy_v3_v3(vec, ob->obmat[3]);
sub_v3_v3(vec, ob->size);
DO_MINMAX(vec, min, max);
- break;
}
}
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index fca8d470dc1..4e3840832bb 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -1562,8 +1562,7 @@ static void initialize_all_particles(ParticleSimulationData *sim)
}
}
}
-/* sets particle to the emitter surface with initial velocity & rotation */
-void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime, float cfra)
+void psys_get_birth_coordinates(ParticleSimulationData *sim, ParticleData *pa, ParticleKey *state, float dtime, float cfra)
{
Object *ob = sim->ob;
ParticleSystem *psys = sim->psys;
@@ -1575,17 +1574,6 @@ void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime,
float q_phase[4];
int p = pa - psys->particles;
part=psys->part;
-
- /* get precise emitter matrix if particle is born */
- if(part->type!=PART_HAIR && dtime > 0.f && pa->time < cfra && pa->time >= sim->psys->cfra) {
- /* we have to force RECALC_ANIM here since where_is_objec_time only does drivers */
- while(ob) {
- BKE_animsys_evaluate_animdata(&ob->id, ob->adt, pa->time, ADT_RECALC_ANIM);
- ob = ob->parent;
- }
- ob = sim->ob;
- where_is_object_time(sim->scene, ob, pa->time);
- }
/* get birth location from object */
if(part->tanfac != 0.f)
@@ -1594,7 +1582,7 @@ void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime,
psys_particle_on_emitter(sim->psmd, part->from,pa->num, pa->num_dmcache, pa->fuv,pa->foffset,loc,nor,0,0,0,0);
/* get possible textural influence */
- psys_get_texture(sim, pa, &ptex, PAMAP_IVEL|PAMAP_LIFE, cfra);
+ psys_get_texture(sim, pa, &ptex, PAMAP_IVEL, cfra);
/* particles live in global space so */
/* let's convert: */
@@ -1654,37 +1642,27 @@ void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime,
mat4_to_quat(rot,ob->obmat);
mul_qt_qtqt(r_rot,r_rot,rot);
}
-#if 0
- }
-#endif
if(part->phystype==PART_PHYS_BOIDS && pa->boid) {
- BoidParticle *bpa = pa->boid;
float dvec[3], q[4], mat[3][3];
- copy_v3_v3(pa->state.co,loc);
+ copy_v3_v3(state->co,loc);
/* boids don't get any initial velocity */
- zero_v3(pa->state.vel);
+ zero_v3(state->vel);
/* boids store direction in ave */
if(fabsf(nor[2])==1.0f) {
- sub_v3_v3v3(pa->state.ave, loc, ob->obmat[3]);
- normalize_v3(pa->state.ave);
+ sub_v3_v3v3(state->ave, loc, ob->obmat[3]);
+ normalize_v3(state->ave);
}
else {
- VECCOPY(pa->state.ave, nor);
+ VECCOPY(state->ave, nor);
}
- /* and gravity in r_ve */
- bpa->gravity[0] = bpa->gravity[1] = 0.0f;
- bpa->gravity[2] = -1.0f;
- if((sim->scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY)
- && sim->scene->physics_settings.gravity[2]!=0.0f)
- bpa->gravity[2] = sim->scene->physics_settings.gravity[2];
/* calculate rotation matrix */
- project_v3_v3v3(dvec, r_vel, pa->state.ave);
- sub_v3_v3v3(mat[0], pa->state.ave, dvec);
+ project_v3_v3v3(dvec, r_vel, state->ave);
+ sub_v3_v3v3(mat[0], state->ave, dvec);
normalize_v3(mat[0]);
negate_v3_v3(mat[2], r_vel);
normalize_v3(mat[2]);
@@ -1692,12 +1670,7 @@ void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime,
/* apply rotation */
mat3_to_quat_is_ok( q,mat);
- copy_qt_qt(pa->state.rot, q);
-
- bpa->data.health = part->boids->health;
- bpa->data.mode = eBoidMode_InAir;
- bpa->data.state_id = ((BoidState*)part->boids->states.first)->id;
- bpa->data.acc[0]=bpa->data.acc[1]=bpa->data.acc[2]=0.0f;
+ copy_qt_qt(state->rot, q);
}
else {
/* conversion done so now we apply new: */
@@ -1710,7 +1683,7 @@ void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime,
/* *emitter velocity */
if(dtime != 0.f && part->obfac != 0.f){
- sub_v3_v3v3(vel, loc, pa->state.co);
+ sub_v3_v3v3(vel, loc, state->co);
mul_v3_fl(vel, part->obfac/dtime);
}
@@ -1747,13 +1720,13 @@ void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime,
if(part->partfac != 0.f)
madd_v3_v3fl(vel, p_vel, part->partfac);
- mul_v3_v3fl(pa->state.vel, vel, ptex.ivel);
+ mul_v3_v3fl(state->vel, vel, ptex.ivel);
/* -location from emitter */
- copy_v3_v3(pa->state.co,loc);
+ copy_v3_v3(state->co,loc);
/* -rotation */
- unit_qt(pa->state.rot);
+ unit_qt(state->rot);
if(part->rotmode){
/* create vector into which rotation is aligned */
@@ -1793,32 +1766,74 @@ void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime,
axis_angle_to_quat( q_phase,x_vec, phasefac*(float)M_PI);
/* combine base rotation & phase */
- mul_qt_qtqt(pa->state.rot, rot, q_phase);
+ mul_qt_qtqt(state->rot, rot, q_phase);
}
/* -angular velocity */
- zero_v3(pa->state.ave);
+ zero_v3(state->ave);
if(part->avemode){
switch(part->avemode){
case PART_AVE_SPIN:
- copy_v3_v3(pa->state.ave, vel);
+ copy_v3_v3(state->ave, vel);
break;
case PART_AVE_RAND:
- copy_v3_v3(pa->state.ave, r_ave);
+ copy_v3_v3(state->ave, r_ave);
break;
}
- normalize_v3(pa->state.ave);
- mul_v3_fl(pa->state.ave,part->avefac);
+ normalize_v3(state->ave);
+ mul_v3_fl(state->ave, part->avefac);
}
}
+}
+/* sets particle to the emitter surface with initial velocity & rotation */
+void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime, float cfra)
+{
+ Object *ob = sim->ob;
+ ParticleSystem *psys = sim->psys;
+ ParticleSettings *part;
+ ParticleTexture ptex;
+ int p = pa - psys->particles;
+ part=psys->part;
+
+ /* get precise emitter matrix if particle is born */
+ if(part->type!=PART_HAIR && dtime > 0.f && pa->time < cfra && pa->time >= sim->psys->cfra) {
+ /* we have to force RECALC_ANIM here since where_is_objec_time only does drivers */
+ while(ob) {
+ BKE_animsys_evaluate_animdata(&ob->id, ob->adt, pa->time, ADT_RECALC_ANIM);
+ ob = ob->parent;
+ }
+ ob = sim->ob;
+ where_is_object_time(sim->scene, ob, pa->time);
+ }
+
+ psys_get_birth_coordinates(sim, pa, &pa->state, dtime, cfra);
+
+ if(part->phystype==PART_PHYS_BOIDS && pa->boid) {
+ BoidParticle *bpa = pa->boid;
+
+ /* and gravity in r_ve */
+ bpa->gravity[0] = bpa->gravity[1] = 0.0f;
+ bpa->gravity[2] = -1.0f;
+ if((sim->scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY)
+ && sim->scene->physics_settings.gravity[2]!=0.0f)
+ bpa->gravity[2] = sim->scene->physics_settings.gravity[2];
+
+ bpa->data.health = part->boids->health;
+ bpa->data.mode = eBoidMode_InAir;
+ bpa->data.state_id = ((BoidState*)part->boids->states.first)->id;
+ bpa->data.acc[0]=bpa->data.acc[1]=bpa->data.acc[2]=0.0f;
+ }
if(part->type == PART_HAIR){
pa->lifetime = 100.0f;
}
else{
+ /* get possible textural influence */
+ psys_get_texture(sim, pa, &ptex, PAMAP_LIFE, cfra);
+
pa->lifetime = part->lifetime * ptex.life;
if(part->randlife != 0.0f)
@@ -1904,6 +1919,7 @@ static void set_keyed_keys(ParticleSimulationData *sim)
PARTICLE_P;
ParticleKey *key;
int totpart = psys->totpart, k, totkeys = psys->totkeyed;
+ int keyed_flag = 0;
ksim.scene= sim->scene;
@@ -1933,6 +1949,8 @@ static void set_keyed_keys(ParticleSimulationData *sim)
for(k=0; k<totkeys; k++) {
ksim.ob = pt->ob ? pt->ob : sim->ob;
ksim.psys = BLI_findlink(&ksim.ob->particlesystem, pt->psys - 1);
+ keyed_flag = (ksim.psys->flag & PSYS_KEYED);
+ ksim.psys->flag &= ~PSYS_KEYED;
LOOP_PARTICLES {
key = pa->keys + k;
@@ -1956,6 +1974,8 @@ static void set_keyed_keys(ParticleSimulationData *sim)
if(psys->flag & PSYS_KEYED_TIMING && pt->duration!=0.0f)
k++;
+ ksim.psys->flag |= keyed_flag;
+
pt = (pt->next && pt->next->flag & PTARGET_VALID)? pt->next : psys->targets.first;
}
diff --git a/source/blender/blenkernel/intern/sca.c b/source/blender/blenkernel/intern/sca.c
index 16cef67ea6d..0d523599598 100644
--- a/source/blender/blenkernel/intern/sca.c
+++ b/source/blender/blenkernel/intern/sca.c
@@ -430,6 +430,7 @@ void init_actuator(bActuator *act)
act->data= MEM_callocN(sizeof(bCameraActuator), "camact");
ca = act->data;
ca->axis = ACT_CAMERA_X;
+ ca->damping = 1.0/32.0;
break;
case ACT_EDIT_OBJECT:
act->data= MEM_callocN(sizeof(bEditObjectActuator), "editobact");
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index 11cdcddae3a..51eaba3c05b 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -476,8 +476,7 @@ Scene *add_scene(const char *name)
sce->audio.doppler_factor = 1.0;
sce->audio.speed_of_sound = 343.3;
- strcpy(sce->r.backbuf, "//backbuf");
- strcpy(sce->r.pic, U.renderdir);
+ BLI_strncpy(sce->r.pic, U.renderdir, sizeof(sce->r.pic));
BLI_init_rctf(&sce->r.safety, 0.1f, 0.9f, 0.1f, 0.9f);
sce->r.osa= 8;
diff --git a/source/blender/blenkernel/intern/seqeffects.c b/source/blender/blenkernel/intern/seqeffects.c
index d2f05a8ca53..fbb5a77fa04 100644
--- a/source/blender/blenkernel/intern/seqeffects.c
+++ b/source/blender/blenkernel/intern/seqeffects.c
@@ -1582,7 +1582,7 @@ typedef struct WipeZone {
static void precalc_wipe_zone(WipeZone *wipezone, WipeVars *wipe, int xo, int yo)
{
wipezone->flip = (wipe->angle < 0);
- wipezone->angle = pow(fabsf(wipe->angle)/45.0f, log(xo)/log(2.0f));
+ wipezone->angle = pow(fabsf(wipe->angle)/45.0f, log(xo)/M_LN2);
wipezone->xo = xo;
wipezone->yo = yo;
wipezone->width = (int)(wipe->edgeWidth*((xo+yo)/2.0f));
@@ -3021,10 +3021,15 @@ void sequence_effect_speed_rebuild_map(Scene *scene, Sequence * seq, int force)
/* if not already done, load / initialize data */
get_sequence_effect(seq);
- if (!(force || seq->len != v->length || !v->frameMap)) {
+ if ( (force == FALSE) &&
+ (seq->len == v->length) &&
+ (v->frameMap != NULL)
+ ) {
return;
}
- if (!seq->seq1) { /* make coverity happy and check for (CID 598)
+ if ( (seq->seq1 == NULL) ||
+ (seq->len < 1)
+ ) { /* make coverity happy and check for (CID 598)
input strip ... */
return;
}
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index 009665f3a1f..b82ac69fc9e 100644
--- a/source/blender/blenkernel/intern/sequencer.c
+++ b/source/blender/blenkernel/intern/sequencer.c
@@ -587,8 +587,22 @@ void calc_sequence(Scene *scene, Sequence *seq)
if (seq->seq1) {
seq->start= seq->startdisp= MAX3(seq->seq1->startdisp, seq->seq2->startdisp, seq->seq3->startdisp);
seq->enddisp= MIN3(seq->seq1->enddisp, seq->seq2->enddisp, seq->seq3->enddisp);
+ /* we cant help if strips don't overlap, it wont give useful results.
+ * but at least ensure 'len' is never negative which causes bad bugs elsewhere. */
+ if(seq->enddisp < seq->startdisp) {
+ /* simple start/end swap */
+ seq->start= seq->enddisp;
+ seq->enddisp = seq->startdisp;
+ seq->startdisp= seq->start;
+ seq->flag |= SEQ_INVALID_EFFECT;
+ }
+ else {
+ seq->flag &= ~SEQ_INVALID_EFFECT;
+ }
+
seq->len= seq->enddisp - seq->startdisp;
- } else {
+ }
+ else {
calc_sequence_disp(scene, seq);
}
diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h
index 634634f02e5..b34b9c4b70f 100644
--- a/source/blender/blenlib/BLI_math_geom.h
+++ b/source/blender/blenlib/BLI_math_geom.h
@@ -162,6 +162,9 @@ void barycentric_transform(float pt_tar[3], float const pt_src[3],
void barycentric_weights_v2(const float v1[2], const float v2[2], const float v3[2],
const float co[2], float w[3]);
+void resolve_tri_uv(float uv[2], const float st[2], const float st0[2], const float st1[2], const float st2[2]);
+void resolve_quad_uv(float uv[2], const float st[2], const float st0[2], const float st1[2], const float st2[2], const float st3[2]);
+
/***************************** View & Projection *****************************/
void lookat_m4(float mat[4][4], float vx, float vy,
diff --git a/source/blender/blenlib/BLI_math_vector.h b/source/blender/blenlib/BLI_math_vector.h
index 5f26bff0ad9..decfa22c3e6 100644
--- a/source/blender/blenlib/BLI_math_vector.h
+++ b/source/blender/blenlib/BLI_math_vector.h
@@ -58,6 +58,8 @@ MINLINE void swap_v4_v4(float a[4], float b[4]);
/********************************* Arithmetic ********************************/
+MINLINE void add_v3_fl(float r[3], float f);
+MINLINE void add_v4_fl(float r[4], float f);
MINLINE void add_v2_v2(float r[2], const float a[2]);
MINLINE void add_v2_v2v2(float r[2], const float a[2], const float b[2]);
MINLINE void add_v3_v3(float r[3], const float a[3]);
diff --git a/source/blender/blenlib/BLI_utildefines.h b/source/blender/blenlib/BLI_utildefines.h
index a376d048412..9af55601ff7 100644
--- a/source/blender/blenlib/BLI_utildefines.h
+++ b/source/blender/blenlib/BLI_utildefines.h
@@ -103,6 +103,12 @@
#define FTOCHAR(val) ((val)<=0.0f)? 0 : (((val)>(1.0f-0.5f/255.0f))? 255 : (char)((255.0f*(val))+0.5f))
#define FTOUSHORT(val) ((val >= 1.0f-0.5f/65535)? 65535: (val <= 0.0f)? 0: (unsigned short)(val*65535.0f + 0.5f))
+#define F3TOCHAR3(v2,v1) (v1)[0]=FTOCHAR((v2[0])); (v1)[1]=FTOCHAR((v2[1])); (v1)[2]=FTOCHAR((v2[2]))
+#define F3TOCHAR4(v2,v1) { (v1)[0]=FTOCHAR((v2[0])); (v1)[1]=FTOCHAR((v2[1])); (v1)[2]=FTOCHAR((v2[2])); \
+ (v1)[3]=FTOCHAR((v2[3])); (v1)[3] = 255; }
+#define F4TOCHAR4(v2,v1) { (v1)[0]=FTOCHAR((v2[0])); (v1)[1]=FTOCHAR((v2[1])); (v1)[2]=FTOCHAR((v2[2])); \
+ (v1)[3]=FTOCHAR((v2[3])); (v1)[3]=FTOCHAR((v2[3])); }
+
#define VECCOPY(v1,v2) {*(v1)= *(v2); *(v1+1)= *(v2+1); *(v1+2)= *(v2+2);}
#define VECCOPY2D(v1,v2) {*(v1)= *(v2); *(v1+1)= *(v2+1);}
diff --git a/source/blender/blenlib/intern/math_base_inline.c b/source/blender/blenlib/intern/math_base_inline.c
index d37f1d6c5f0..2a2b1100fd9 100644
--- a/source/blender/blenlib/intern/math_base_inline.c
+++ b/source/blender/blenlib/intern/math_base_inline.c
@@ -114,7 +114,7 @@ MINLINE float shell_angle_to_dist(const float angle)
/* used for zoom values*/
MINLINE float power_of_2(float val)
{
- return (float)pow(2.0, ceil(log((double)val) / log(2.0)));
+ return (float)pow(2.0, ceil(log((double)val) / M_LN2));
}
MINLINE float minf(float a, float b)
diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c
index 5979a24c807..96ed788a49f 100644
--- a/source/blender/blenlib/intern/math_geom.c
+++ b/source/blender/blenlib/intern/math_geom.c
@@ -1809,6 +1809,80 @@ void interp_cubic_v3(float x[3], float v[3], const float x1[3], const float v1[3
v[2]= 3*a[2]*t2 + 2*b[2]*t + v1[2];
}
+/* unfortunately internal calculations have to be done at double precision to achieve correct/stable results. */
+
+#define IS_ZERO(x) ((x>(-DBL_EPSILON) && x<DBL_EPSILON) ? 1 : 0)
+
+/* Barycentric reverse */
+void resolve_tri_uv(float uv[2], const float st[2], const float st0[2], const float st1[2], const float st2[2])
+{
+ /* find UV such that
+ t= u*t0 + v*t1 + (1-u-v)*t2
+ u*(t0-t2) + v*(t1-t2)= t-t2 */
+ const double a= st0[0]-st2[0], b= st1[0]-st2[0];
+ const double c= st0[1]-st2[1], d= st1[1]-st2[1];
+ const double det= a*d - c*b;
+
+ if(IS_ZERO(det)==0) { /* det should never be zero since the determinant is the signed ST area of the triangle. */
+ const double x[]= {st[0]-st2[0], st[1]-st2[1]};
+
+ uv[0]= (float)((d*x[0] - b*x[1])/det);
+ uv[1]= (float)(((-c)*x[0] + a*x[1])/det);
+ } else zero_v2(uv);
+}
+
+/* bilinear reverse */
+void resolve_quad_uv(float uv[2], const float st[2], const float st0[2], const float st1[2], const float st2[2], const float st3[2])
+{
+ const double signed_area= (st0[0]*st1[1] - st0[1]*st1[0]) + (st1[0]*st2[1] - st1[1]*st2[0]) +
+ (st2[0]*st3[1] - st2[1]*st3[0]) + (st3[0]*st0[1] - st3[1]*st0[0]);
+
+ /* X is 2D cross product (determinant)
+ A= (p0-p) X (p0-p3)*/
+ const double a= (st0[0]-st[0])*(st0[1]-st3[1]) - (st0[1]-st[1])*(st0[0]-st3[0]);
+
+ /* B= ( (p0-p) X (p1-p2) + (p1-p) X (p0-p3) ) / 2 */
+ const double b= 0.5 * ( ((st0[0]-st[0])*(st1[1]-st2[1]) - (st0[1]-st[1])*(st1[0]-st2[0])) +
+ ((st1[0]-st[0])*(st0[1]-st3[1]) - (st1[1]-st[1])*(st0[0]-st3[0])) );
+
+ /* C = (p1-p) X (p1-p2) */
+ const double fC= (st1[0]-st[0])*(st1[1]-st2[1]) - (st1[1]-st[1])*(st1[0]-st2[0]);
+ const double denom= a - 2*b + fC;
+
+ // clear outputs
+ zero_v2(uv);
+
+ if(IS_ZERO(denom)!=0) {
+ const double fDen= a-fC;
+ if(IS_ZERO(fDen)==0)
+ uv[0]= (float)(a / fDen);
+ } else {
+ const double desc_sq= b*b - a*fC;
+ const double desc= sqrt(desc_sq<0.0?0.0:desc_sq);
+ const double s= signed_area>0 ? (-1.0) : 1.0;
+
+ uv[0]= (float)(( (a-b) + s * desc ) / denom);
+ }
+
+ /* find UV such that
+ fST = (1-u)(1-v)*ST0 + u*(1-v)*ST1 + u*v*ST2 + (1-u)*v*ST3 */
+ {
+ const double denom_s= (1-uv[0])*(st0[0]-st3[0]) + uv[0]*(st1[0]-st2[0]);
+ const double denom_t= (1-uv[0])*(st0[1]-st3[1]) + uv[0]*(st1[1]-st2[1]);
+ int i= 0; double denom= denom_s;
+
+ if(fabs(denom_s)<fabs(denom_t)) {
+ i= 1;
+ denom=denom_t;
+ }
+
+ if(IS_ZERO(denom)==0)
+ uv[1]= (float) (( (1-uv[0])*(st0[i]-st[i]) + uv[0]*(st1[i]-st[i]) ) / denom);
+ }
+}
+
+#undef IS_ZERO
+
/***************************** View & Projection *****************************/
void orthographic_m4(float matrix[][4], const float left, const float right, const float bottom, const float top, const float nearClip, const float farClip)
diff --git a/source/blender/blenlib/intern/math_vector_inline.c b/source/blender/blenlib/intern/math_vector_inline.c
index 9f6a8afe2d5..e2b7c770356 100644
--- a/source/blender/blenlib/intern/math_vector_inline.c
+++ b/source/blender/blenlib/intern/math_vector_inline.c
@@ -102,6 +102,21 @@ MINLINE void swap_v4_v4(float a[4], float b[4])
/********************************* Arithmetic ********************************/
+MINLINE void add_v3_fl(float r[3], float f)
+{
+ r[0] += f;
+ r[1] += f;
+ r[2] += f;
+}
+
+MINLINE void add_v4_fl(float r[4], float f)
+{
+ r[0] += f;
+ r[1] += f;
+ r[2] += f;
+ r[3] += f;
+}
+
MINLINE void add_v2_v2(float *r, const float *a)
{
r[0] += a[0];
diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c
index e0a08d0b890..af87707fb90 100644
--- a/source/blender/blenlib/intern/path_util.c
+++ b/source/blender/blenlib/intern/path_util.c
@@ -153,7 +153,7 @@ void BLI_stringenc(char *string, const char *head, const char *tail, unsigned sh
int BLI_split_name_num(char *left, int *nr, const char *name, const char delim)
{
int a;
-
+
*nr= 0;
a= strlen(name);
memcpy(left, name, (a + 1) * sizeof(char));
@@ -216,13 +216,13 @@ int BLI_uniquename_cb(int (*unique_check)(void *, const char *), void *arg, cons
int number;
int len= BLI_split_name_num(left, &number, name, delim);
do {
- int newlen= BLI_snprintf(tempname, name_len, "%s%c%03d", left, delim, number);
+ int newlen= BLI_snprintf(tempname, name_len, "%s%c%03d", left, delim, ++number);
if(newlen >= name_len) {
len -= ((newlen + 1) - name_len);
if(len < 0) len= number= 0;
left[len]= '\0';
}
- } while(number++, unique_check(arg, tempname));
+ } while(unique_check(arg, tempname));
BLI_strncpy(name, tempname, name_len);
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index c15acb4f5ca..1e604c45772 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -1723,7 +1723,6 @@ static void lib_link_fcurves(FileData *fd, ID *id, ListBase *list)
static void direct_link_fmodifiers(FileData *fd, ListBase *list)
{
FModifier *fcm;
- int a;
for (fcm= list->first; fcm; fcm= fcm->next) {
/* relink general data */
@@ -1739,6 +1738,7 @@ static void direct_link_fmodifiers(FileData *fd, ListBase *list)
data->coefficients= newdataadr(fd, data->coefficients);
if(fd->flags & FD_FLAGS_SWITCH_ENDIAN) {
+ unsigned int a;
for(a = 0; a < data->arraysize; a++)
SWITCH_INT(data->coefficients[a]);
}
@@ -3843,26 +3843,10 @@ static void lib_link_object(FileData *fd, Main *main)
if(smd && smd->type == MOD_SMOKE_TYPE_DOMAIN && smd->domain)
{
- smd->domain->coll_group = newlibadr_us(fd, ob->id.lib, smd->domain->coll_group);
- smd->domain->eff_group = newlibadr_us(fd, ob->id.lib, smd->domain->eff_group);
- smd->domain->fluid_group = newlibadr_us(fd, ob->id.lib, smd->domain->fluid_group);
-
- smd->domain->effector_weights->group = newlibadr(fd, ob->id.lib, smd->domain->effector_weights->group);
-
smd->domain->flags |= MOD_SMOKE_FILE_LOAD; /* flag for refreshing the simulation after loading */
}
}
- {
- ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
-
- if(clmd)
- {
- clmd->sim_parms->effector_weights->group = newlibadr(fd, ob->id.lib, clmd->sim_parms->effector_weights->group);
- clmd->coll_parms->group= newlibadr(fd, ob->id.lib, clmd->coll_parms->group);
- }
- }
-
/* texture field */
if(ob->pd)
lib_link_partdeflect(fd, &ob->id, ob->pd);
@@ -5658,11 +5642,10 @@ static BHead *read_data_into_oldnewmap(FileData *fd, BHead *bhead, const char *a
while(bhead && bhead->code==DATA) {
void *data;
#if 0
- /* XXX DUMB DEBUGGING OPTION TO GIVE NAMES for guarded malloc errors */
+ /* XXX DUMB DEBUGGING OPTION TO GIVE NAMES for guarded malloc errors */
short *sp= fd->filesdna->structs[bhead->SDNAnr];
- char *allocname = fd->filesdna->types[ sp[0] ];
char *tmp= malloc(100);
-
+ allocname = fd->filesdna->types[ sp[0] ];
strcpy(tmp, allocname);
data= read_struct(fd, bhead, tmp);
#else
@@ -6280,7 +6263,7 @@ static void area_add_header_region(ScrArea *sa, ListBase *lb)
BLI_addtail(lb, ar);
ar->regiontype= RGN_TYPE_HEADER;
- if(sa->headertype==1)
+ if(sa->headertype==HEADERDOWN)
ar->alignment= RGN_ALIGN_BOTTOM;
else
ar->alignment= RGN_ALIGN_TOP;
@@ -11664,6 +11647,21 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
}
}
}
+
+ {
+ /* add default value for behind strength of camera actuator */
+ Object *ob;
+ bActuator *act;
+ for(ob = main->object.first; ob; ob= ob->id.next) {
+ for(act= ob->actuators.first; act; act= act->next) {
+ if (act->type == ACT_CAMERA) {
+ bCameraActuator *ba= act->data;
+
+ ba->damping = 1.0/32.0;
+ }
+ }
+ }
+ }
}
/* WATCH IT!!!: pointers from libdata have not been converted yet here! */
@@ -12723,7 +12721,6 @@ static int object_in_any_scene(Main *mainvar, Object *ob)
return 0;
}
-/* when *lib set, it also does objects that were in the appended group */
static void give_base_to_objects(Main *mainvar, Scene *sce, Library *lib, const short idcode, const short is_link)
{
Object *ob;
@@ -12758,8 +12755,14 @@ static void give_base_to_objects(Main *mainvar, Scene *sce, Library *lib, const
/* when appending, make sure any indirectly loaded objects
* get a base else they cant be accessed at all [#27437] */
if(ob->id.us==1 && is_link==FALSE && ob->id.lib==lib) {
- if(object_in_any_scene(mainvar, ob)==0) {
- do_it= 1;
+
+ /* we may be appending from a scene where we already
+ * have a linked object which is not in any scene [#27616] */
+ if((ob->id.flag & LIB_PRE_EXISTING)==0) {
+
+ if(object_in_any_scene(mainvar, ob)==0) {
+ do_it= 1;
+ }
}
}
}
@@ -12780,7 +12783,6 @@ static void give_base_to_objects(Main *mainvar, Scene *sce, Library *lib, const
}
}
-/* when *lib set, it also does objects that were in the appended group */
static void give_base_to_groups(Main *mainvar, Scene *scene)
{
Group *group;
diff --git a/source/blender/collada/DocumentImporter.cpp b/source/blender/collada/DocumentImporter.cpp
index 72341e1caa2..10e6d611cc5 100644
--- a/source/blender/collada/DocumentImporter.cpp
+++ b/source/blender/collada/DocumentImporter.cpp
@@ -959,12 +959,12 @@ bool DocumentImporter::writeLight( const COLLADAFW::Light* light )
if(IS_EQ(linatt, 0.0f) && quadatt > 0.0f) {
att2 = quadatt;
- d = (1.0f/quadatt) * 2;
+ d = sqrt(1.0f/quadatt);
}
// linear light
else if(IS_EQ(quadatt, 0.0f) && linatt > 0.0f) {
att1 = linatt;
- d = (1.0f/linatt) * 2;
+ d = (1.0f/linatt);
} else if (IS_EQ(constatt, 1.0f)) {
att1 = 1.0f;
} else {
@@ -987,9 +987,12 @@ bool DocumentImporter::writeLight( const COLLADAFW::Light* light )
case COLLADAFW::Light::SPOT_LIGHT:
{
lamp->type = LA_SPOT;
- lamp->falloff_type = LA_FALLOFF_INVSQUARE;
lamp->att1 = att1;
lamp->att2 = att2;
+ if(IS_EQ(att1, 0.0f) && att2 > 0)
+ lamp->falloff_type = LA_FALLOFF_INVSQUARE;
+ if(IS_EQ(att2, 0.0f) && att1 > 0)
+ lamp->falloff_type = LA_FALLOFF_INVLINEAR;
lamp->spotsize = light->getFallOffAngle().getValue();
lamp->spotblend = light->getFallOffExponent().getValue();
}
@@ -1004,9 +1007,12 @@ bool DocumentImporter::writeLight( const COLLADAFW::Light* light )
case COLLADAFW::Light::POINT_LIGHT:
{
lamp->type = LA_LOCAL;
- lamp->falloff_type = LA_FALLOFF_INVSQUARE;
lamp->att1 = att1;
lamp->att2 = att2;
+ if(IS_EQ(att1, 0.0f) && att2 > 0)
+ lamp->falloff_type = LA_FALLOFF_INVSQUARE;
+ if(IS_EQ(att2, 0.0f) && att1 > 0)
+ lamp->falloff_type = LA_FALLOFF_INVLINEAR;
}
break;
case COLLADAFW::Light::UNDEFINED:
diff --git a/source/blender/collada/EffectExporter.cpp b/source/blender/collada/EffectExporter.cpp
index ff714533199..0bbf714137e 100644
--- a/source/blender/collada/EffectExporter.cpp
+++ b/source/blender/collada/EffectExporter.cpp
@@ -273,7 +273,7 @@ void EffectsExporter::operator()(Material *ma, Object *ob)
std::string uvname = strlen(t->uvname) ? t->uvname : active_uv;
// color
- if (t->mapto & MAP_COL) {
+ if (t->mapto & MAP_COL | MAP_COLSPEC) {
ep.setDiffuse(createTexture(ima, uvname, sampler));
}
// ambient
diff --git a/source/blender/collada/LightExporter.cpp b/source/blender/collada/LightExporter.cpp
index 89599c62768..12ccf77f6ad 100644
--- a/source/blender/collada/LightExporter.cpp
+++ b/source/blender/collada/LightExporter.cpp
@@ -68,20 +68,18 @@ void LightsExporter::operator()(Object *ob)
std::string la_name(id_name(la));
COLLADASW::Color col(la->r * la->energy, la->g * la->energy, la->b * la->energy);
float e, d, constatt, linatt, quadatt;
- float r;
d = la->dist;
- r = d/2.0f;
constatt = 1.0f;
if(la->falloff_type==LA_FALLOFF_INVLINEAR) {
- linatt = 1.0f / r;
+ linatt = 1.0f / d;
quadatt = 0.0f;
}
else {
linatt = 0.0f;
- quadatt = 1.0f / r;
+ quadatt = 1.0f / (d * d);
}
// sun
diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c
index 438c6e7e95e..9eb9e3ecd9a 100644
--- a/source/blender/editors/animation/anim_channels_edit.c
+++ b/source/blender/editors/animation/anim_channels_edit.c
@@ -1903,6 +1903,7 @@ static void ANIM_OT_channels_select_border(wmOperatorType *ot)
ot->invoke= WM_border_select_invoke;
ot->exec= animchannels_borderselect_exec;
ot->modal= WM_border_select_modal;
+ ot->cancel= WM_border_select_cancel;
ot->poll= animedit_poll_channels_nla_tweakmode_off;
diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c
index f61c1ff7962..1fb2317cdbb 100644
--- a/source/blender/editors/animation/anim_markers.c
+++ b/source/blender/editors/animation/anim_markers.c
@@ -717,7 +717,7 @@ static void ed_marker_move_apply(wmOperator *op)
}
/* only for modal */
-static void ed_marker_move_cancel(bContext *C, wmOperator *op)
+static int ed_marker_move_cancel(bContext *C, wmOperator *op)
{
RNA_int_set(op->ptr, "frames", 0);
ed_marker_move_apply(op);
@@ -725,6 +725,8 @@ static void ed_marker_move_cancel(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_SCENE|ND_MARKERS, NULL);
WM_event_add_notifier(C, NC_ANIMATION|ND_MARKERS, NULL);
+
+ return OPERATOR_CANCELLED;
}
@@ -886,6 +888,7 @@ static void MARKER_OT_move(wmOperatorType *ot)
ot->invoke= ed_marker_move_invoke_wrapper;
ot->modal= ed_marker_move_modal;
ot->poll= ed_markers_poll_selected_markers;
+ ot->cancel= ed_marker_move_cancel;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING|OPTYPE_GRAB_POINTER;
@@ -980,6 +983,7 @@ static void MARKER_OT_duplicate(wmOperatorType *ot)
ot->invoke= ed_marker_duplicate_invoke_wrapper;
ot->modal= ed_marker_move_modal;
ot->poll= ed_markers_poll_selected_markers;
+ ot->cancel= ed_marker_move_cancel;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
@@ -1185,6 +1189,7 @@ static void MARKER_OT_select_border(wmOperatorType *ot)
ot->exec= ed_marker_border_select_exec;
ot->invoke= ed_marker_select_border_invoke_wrapper;
ot->modal= WM_border_select_modal;
+ ot->cancel= WM_border_select_cancel;
ot->poll= ed_markers_poll_markers_exist;
diff --git a/source/blender/editors/animation/anim_ops.c b/source/blender/editors/animation/anim_ops.c
index 93d99c59a0e..7a94a21d41e 100644
--- a/source/blender/editors/animation/anim_ops.c
+++ b/source/blender/editors/animation/anim_ops.c
@@ -199,8 +199,8 @@ static int previewrange_define_exec(bContext *C, wmOperator *op)
* - must clamp within allowable limits
* - end must not be before start (though this won't occur most of the time)
*/
- if (sfra < 1) sfra = 1.0f;
- if (efra < 1) efra = 1.0f;
+ FRAMENUMBER_MIN_CLAMP(sfra);
+ FRAMENUMBER_MIN_CLAMP(efra);
if (efra < sfra) efra= sfra;
scene->r.flag |= SCER_PRV_RANGE;
@@ -224,6 +224,7 @@ static void ANIM_OT_previewrange_set(wmOperatorType *ot)
ot->invoke= WM_border_select_invoke;
ot->exec= previewrange_define_exec;
ot->modal= WM_border_select_modal;
+ ot->cancel= WM_border_select_cancel;
ot->poll= ED_operator_animview_active;
diff --git a/source/blender/editors/datafiles/CMakeLists.txt b/source/blender/editors/datafiles/CMakeLists.txt
index 8761297b979..ae86905a91d 100644
--- a/source/blender/editors/datafiles/CMakeLists.txt
+++ b/source/blender/editors/datafiles/CMakeLists.txt
@@ -29,41 +29,48 @@ set(INC_SYS
set(SRC
Bfont.c
- add.png.c
bfont.ttf.c
- blenderbuttons.c
- blob.png.c
- blur.png.c
bmonofont.ttf.c
- clay.png.c
- clone.png.c
- crease.png.c
- darken.png.c
- draw.png.c
- fill.png.c
- flatten.png.c
- grab.png.c
- inflate.png.c
- layer.png.c
- lighten.png.c
- mix.png.c
- multiply.png.c
- nudge.png.c
- pinch.png.c
- preview.blend.c
- prvicons.c
- scrape.png.c
- smear.png.c
- smooth.png.c
- snake_hook.png.c
- soften.png.c
- splash.png.c
startup.blend.c
- subtract.png.c
- texdraw.png.c
- thumb.png.c
- twist.png.c
- vertexdraw.png.c
+ preview.blend.c
)
+if(NOT WITH_HEADLESS)
+ list(APPEND SRC
+ splash.png.c
+ blenderbuttons.c
+
+ # brushes
+ add.png.c
+ blob.png.c
+ blur.png.c
+ clay.png.c
+ clone.png.c
+ crease.png.c
+ darken.png.c
+ draw.png.c
+ fill.png.c
+ flatten.png.c
+ grab.png.c
+ inflate.png.c
+ layer.png.c
+ lighten.png.c
+ mix.png.c
+ multiply.png.c
+ nudge.png.c
+ pinch.png.c
+ prvicons.c
+ scrape.png.c
+ smear.png.c
+ smooth.png.c
+ snake_hook.png.c
+ soften.png.c
+ subtract.png.c
+ texdraw.png.c
+ thumb.png.c
+ twist.png.c
+ vertexdraw.png.c
+ )
+endif()
+
blender_add_lib(bf_editor_datafiles "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/source/blender/editors/datafiles/startup.blend.c b/source/blender/editors/datafiles/startup.blend.c
index 6900f458a2b..1121eb5a299 100644
--- a/source/blender/editors/datafiles/startup.blend.c
+++ b/source/blender/editors/datafiles/startup.blend.c
@@ -8854,8 +8854,8 @@ char datatoc_startup_blend[]= {
0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,114,114,114,255,
0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,127,
0, 0, 0,255, 0, 0, 0,255,255,255,255,255,160,160,160,100,127,112,112,100, 0, 0, 0, 0, 64, 64, 64,255, 0, 0, 0,255,
-241, 88, 0,255, 0, 0, 0, 40,255,140, 25,255, 8, 48, 8,255, 85,187, 85,255,255,255,255,255, 0, 0, 0,255,255,133, 0,255,
- 0, 0, 0,255,255,160, 0,255,219, 37, 18,255,255, 32, 32,255, 75, 75, 75,255,204, 0,153,255, 0, 0, 0, 18,255,133, 0, 60,
+241, 88, 0,255, 0, 0, 0, 40,255,170, 64,255, 8, 48, 8,255, 85,187, 85,255,255,255,255,255, 0, 0, 0,255,255,133, 0,255,
+ 0, 0, 0,255,255,160, 0,255,219, 37, 18,255,32, 255,255,255, 75, 75, 75,255,204, 0,153,255, 0, 0, 0, 18,255,133, 0, 60,
255,133, 0,255, 32, 0, 0,255, 0, 32, 0,255, 0, 0,128,255, 0, 0, 0, 0, 34,221,221,255, 35, 97,221,255,200,200,200,255,
80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255,144,144, 0,255,128, 48, 96,255,219, 37, 18,255,240,255, 64,255,
240,144,160,255,255,255,255,255, 0, 0, 0,255,144,144, 0,255, 64,144, 48,255,128, 48, 96,255, 0, 0, 0,255,240,255, 64,255,
diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h
index 5c4dfc6ba3d..8bb77ad43a0 100644
--- a/source/blender/editors/include/ED_mesh.h
+++ b/source/blender/editors/include/ED_mesh.h
@@ -206,10 +206,10 @@ struct bDeformGroup *ED_vgroup_add(struct Object *ob);
struct bDeformGroup *ED_vgroup_add_name(struct Object *ob, const char *name);
void ED_vgroup_delete(struct Object *ob, struct bDeformGroup *defgroup);
void ED_vgroup_select_by_name(struct Object *ob, const char *name);
-void ED_vgroup_data_create(struct ID *id);
+int ED_vgroup_data_create(struct ID *id);
int ED_vgroup_give_array(struct ID *id, struct MDeformVert **dvert_arr, int *dvert_tot);
int ED_vgroup_copy_array(struct Object *ob, struct Object *ob_from);
-void ED_vgroup_mirror(struct Object *ob, int mirror_weights, int flip_vgroups);
+void ED_vgroup_mirror(struct Object *ob, const short mirror_weights, const short flip_vgroups);
int ED_vgroup_object_is_edit_mode(struct Object *ob);
diff --git a/source/blender/editors/include/ED_particle.h b/source/blender/editors/include/ED_particle.h
index 23997e06aef..f2973d0d070 100644
--- a/source/blender/editors/include/ED_particle.h
+++ b/source/blender/editors/include/ED_particle.h
@@ -71,8 +71,9 @@ void PE_undo_push(struct Scene *scene, const char *str);
void PE_undo_step(struct Scene *scene, int step);
void PE_undo(struct Scene *scene);
void PE_redo(struct Scene *scene);
-void PE_undo_menu(struct Scene *scene, struct Object *ob);
int PE_undo_valid(struct Scene *scene);
+void PE_undo_number(struct Scene *scene, int nr);
+char *PE_undo_get_name(struct Scene *scene, int nr, int *active);
#endif /* ED_PARTICLE_H */
diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h
index 93ce82fa483..f2ef4e16852 100644
--- a/source/blender/editors/include/ED_screen.h
+++ b/source/blender/editors/include/ED_screen.h
@@ -90,6 +90,7 @@ void ED_area_headerprint(ScrArea *sa, const char *str);
void ED_area_newspace(struct bContext *C, ScrArea *sa, int type);
void ED_area_prevspace(struct bContext *C, ScrArea *sa);
void ED_area_swapspace(struct bContext *C, ScrArea *sa1, ScrArea *sa2);
+int ED_area_headersize(void);
/* screens */
void ED_screens_initialize(struct wmWindowManager *wm);
@@ -106,7 +107,7 @@ void ED_screen_set_subwinactive(struct bContext *C, struct wmEvent *event);
void ED_screen_exit(struct bContext *C, struct wmWindow *window, struct bScreen *screen);
void ED_screen_animation_timer(struct bContext *C, int redraws, int refresh, int sync, int enable);
void ED_screen_animation_timer_update(struct bScreen *screen, int redraws, int refresh);
-int ED_screen_full_newspace(struct bContext *C, ScrArea *sa, int type);
+ScrArea *ED_screen_full_newspace(struct bContext *C, ScrArea *sa, int type);
void ED_screen_full_prevspace(struct bContext *C, ScrArea *sa);
void ED_screen_full_restore(struct bContext *C, ScrArea *sa);
struct ScrArea *ED_screen_full_toggle(struct bContext *C, struct wmWindow *win, struct ScrArea *sa);
diff --git a/source/blender/editors/include/ED_types.h b/source/blender/editors/include/ED_types.h
index 0218b8d9c2d..c1c31372011 100644
--- a/source/blender/editors/include/ED_types.h
+++ b/source/blender/editors/include/ED_types.h
@@ -40,10 +40,6 @@
#define SELECT 1
#define ACTIVE 2
-/* buttons */
-#define XIC 20
-#define YIC 20
-
/* proposal = put scene pointers on function calls? */
// #define BASACT (scene->basact)
// #define OBACT (BASACT? BASACT->object: NULL)
diff --git a/source/blender/editors/include/ED_util.h b/source/blender/editors/include/ED_util.h
index 50dd2308b6b..5e004fd8d47 100644
--- a/source/blender/editors/include/ED_util.h
+++ b/source/blender/editors/include/ED_util.h
@@ -59,6 +59,7 @@ void ED_undo_redo (struct bContext *C);
void ED_OT_undo (struct wmOperatorType *ot);
void ED_OT_undo_push (struct wmOperatorType *ot);
void ED_OT_redo (struct wmOperatorType *ot);
+void ED_OT_undo_history (struct wmOperatorType *ot);
int ED_undo_operator_repeat(struct bContext *C, struct wmOperator *op);
/* convenience since UI callbacks use this mostly*/
@@ -76,11 +77,7 @@ void undo_editmode_push(struct bContext *C, const char *name,
int (*validate_undo)(void *, void *));
-void *undo_editmode_get_prev (struct Object *ob);
-struct uiBlock *editmode_undohistorymenu(struct bContext *C, struct ARegion *ar, void *arg_unused);
-void undo_editmode_menu (struct bContext *C);
void undo_editmode_clear (void);
-void undo_editmode_step (struct bContext *C, int step);
/* crazyspace.c */
float *crazyspace_get_mapped_editverts(struct Scene *scene, struct Object *obedit);
diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h
index 0adf6633b05..dfe0a304748 100644
--- a/source/blender/editors/include/ED_view3d.h
+++ b/source/blender/editors/include/ED_view3d.h
@@ -265,6 +265,7 @@ struct ARegion *ED_view3d_context_region_unlock(struct bContext *C);
int ED_operator_rv3d_unlock_poll(struct bContext *C);
void ED_view3d_init_mats_rv3d(struct Object *ob, struct RegionView3D *rv3d);
+void ED_view3d_init_mats_rv3d_gl(struct Object *ob, struct RegionView3D *rv3d);
int ED_view3d_scene_layer_set(int lay, const int *values, int *active);
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index d6988aa9618..1a26079800c 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -35,6 +35,7 @@
#define UI_INTERFACE_H
#include "RNA_types.h"
+#include "DNA_userdef_types.h"
/* Struct Declarations */
@@ -100,8 +101,8 @@ typedef struct uiLayout uiLayout;
#define UI_BLOCK_RET_1 4 /* XXX 2.5 not implemented */
#define UI_BLOCK_NUMSELECT 8
/*#define UI_BLOCK_ENTER_OK 16*/ /*UNUSED*/
-/*#define UI_BLOCK_NOSHADOW 32*/ /*UNUSED*/
-/*#define UI_BLOCK_UNUSED 64*/ /*UNUSED*/
+#define UI_BLOCK_CLIPBOTTOM 32
+#define UI_BLOCK_CLIPTOP 64
#define UI_BLOCK_MOVEMOUSE_QUIT 128
#define UI_BLOCK_KEEP_OPEN 256
#define UI_BLOCK_POPUP 512
@@ -622,8 +623,8 @@ void UI_exit(void);
#define UI_LAYOUT_MENU 2
#define UI_LAYOUT_TOOLBAR 3
-#define UI_UNIT_X 20
-#define UI_UNIT_Y 20
+#define UI_UNIT_X U.widget_unit
+#define UI_UNIT_Y U.widget_unit
#define UI_LAYOUT_ALIGN_EXPAND 0
#define UI_LAYOUT_ALIGN_LEFT 1
diff --git a/source/blender/editors/include/UI_interface_icons.h b/source/blender/editors/include/UI_interface_icons.h
index 50b14cb832a..b6837a4b3c9 100644
--- a/source/blender/editors/include/UI_interface_icons.h
+++ b/source/blender/editors/include/UI_interface_icons.h
@@ -49,6 +49,10 @@ typedef struct IconFile {
#define ICON_DEFAULT_HEIGHT 16
#define ICON_DEFAULT_WIDTH 16
+
+#define ICON_DEFAULT_HEIGHT_SCALE (UI_UNIT_Y * 0.8f)
+#define ICON_DEFAULT_WIDTH_SCALE (UI_UNIT_X * 0.8f)
+
#define PREVIEW_DEFAULT_HEIGHT 96
/*
diff --git a/source/blender/editors/interface/CMakeLists.txt b/source/blender/editors/interface/CMakeLists.txt
index 9902cac8857..6dd7af70e33 100644
--- a/source/blender/editors/interface/CMakeLists.txt
+++ b/source/blender/editors/interface/CMakeLists.txt
@@ -63,6 +63,10 @@ if(WITH_INTERNATIONAL)
add_definitions(-DINTERNATIONAL)
endif()
+if(WITH_HEADLESS)
+ add_definitions(-DWITH_HEADLESS)
+endif()
+
if(WITH_PYTHON)
add_definitions(-DWITH_PYTHON)
endif()
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index d139eafc09d..37e4cc7616b 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -74,6 +74,9 @@
#define MENU_ITEM_HEIGHT 20
#define MENU_SEP_HEIGHT 6
+#define PRECISION_FLOAT_MAX 7
+#define PRECISION_FLOAT_MAX_POW 10000000 /* pow(10, PRECISION_FLOAT_MAX) */
+
/*
* a full doc with API notes can be found in bf-blender/trunk/blender/doc/guides/interface_API.txt
*
@@ -449,6 +452,57 @@ void uiCenteredBoundsBlock(uiBlock *block, int addval)
/* link line drawing is not part of buttons or theme.. so we stick with it here */
+static int ui_but_float_precision(uiBut *but, double value)
+{
+ int prec;
+
+ /* first check if prec is 0 and fallback to a simple default */
+ if((prec= (int)but->a2) == 0) {
+ prec= (but->hardmax < 10.001f) ? 3 : 2;
+ }
+
+ /* check on the number of decimal places neede to display
+ * the number, this is so 0.00001 is not displayed as 0.00,
+ * _but_, this is only for small values si 10.0001 will not get
+ * the same treatment */
+ if(value != 0.0 && (value= ABS(value)) < 0.1) {
+ int value_i= (int)((value * PRECISION_FLOAT_MAX_POW) + 0.5);
+ if(value_i != 0) {
+ const int prec_span= 3; /* show: 0.01001, 5 would allow 0.0100001 for eg. */
+ int test_prec;
+ int prec_min= -1;
+ int dec_flag= 0;
+ int i= PRECISION_FLOAT_MAX;
+ while(i && value_i) {
+ if(value_i % 10) {
+ dec_flag |= 1<<i;
+ prec_min= i;
+ }
+ value_i /= 10;
+ i--;
+ }
+
+ /* even though its a small value, if the second last digit is not 0, use it */
+ test_prec = prec_min;
+
+ dec_flag= (dec_flag >> (prec_min + 1)) & ((1 << prec_span) - 1);
+
+ while(dec_flag) {
+ test_prec++;
+ dec_flag = dec_flag >> 1;
+ }
+
+ if(test_prec > prec) {
+ prec= test_prec;
+ }
+ }
+ }
+
+ CLAMP(prec, 1, PRECISION_FLOAT_MAX);
+
+ return prec;
+}
+
static void ui_draw_linkline(uiLinkLine *line)
{
rcti rect;
@@ -892,13 +946,14 @@ void uiDrawBlock(const bContext *C, uiBlock *block)
/* widgets */
for(but= block->buttons.first; but; but= but->next) {
- ui_but_to_pixelrect(&rect, ar, block, but);
+ if(!(but->flag & (UI_HIDDEN|UI_SCROLLED))) {
+ ui_but_to_pixelrect(&rect, ar, block, but);
- if(!(but->flag & UI_HIDDEN) &&
/* XXX: figure out why invalid coordinates happen when closing render window */
/* and material preview is redrawn in main window (temp fix for bug #23848) */
- rect.xmin < rect.xmax && rect.ymin < rect.ymax)
- ui_draw_but(C, ar, &style, but, &rect);
+ if(rect.xmin < rect.xmax && rect.ymin < rect.ymax)
+ ui_draw_but(C, ar, &style, but, &rect);
+ }
}
/* restore matrix */
@@ -1444,8 +1499,8 @@ static void ui_get_but_string_unit(uiBut *but, char *str, int len_max, double va
if(scene->unit.scale_length<0.0001f) scene->unit.scale_length= 1.0f; // XXX do_versions
/* Sanity checks */
- if(precision>7) precision= 7;
- else if(precision==0) precision= 2;
+ if(precision > PRECISION_FLOAT_MAX) precision= PRECISION_FLOAT_MAX;
+ else if(precision==0) precision= 2;
bUnit_AsString(str, len_max, ui_get_but_scale_unit(but, value), precision, scene->unit.system, unit_type>>16, do_split, pad);
}
@@ -1529,10 +1584,7 @@ void ui_get_but_string(uiBut *but, char *str, int maxlen)
ui_get_but_string_unit(but, str, maxlen, value, 0);
}
else {
- int prec= (int)but->a2;
- if(prec==0) prec= 3;
- else CLAMP(prec, 1, 7);
-
+ const int prec= ui_but_float_precision(but, value);
BLI_snprintf(str, maxlen, "%.*f", prec, value);
}
}
@@ -1681,7 +1733,7 @@ void ui_set_but_default(bContext *C, short all)
static double soft_range_round_up(double value, double max)
{
/* round up to .., 0.1, 0.2, 0.5, 1, 2, 5, 10, 20, 50, .. */
- double newmax= pow(10.0, ceil(log(value)/log(10.0)));
+ double newmax= pow(10.0, ceil(log(value)/M_LN10));
if(newmax*0.2 >= max && newmax*0.2 >= value)
return newmax*0.2;
@@ -1694,7 +1746,7 @@ static double soft_range_round_up(double value, double max)
static double soft_range_round_down(double value, double max)
{
/* round down to .., 0.1, 0.2, 0.5, 1, 2, 5, 10, 20, 50, .. */
- double newmax= pow(10.0, floor(log(value)/log(10.0)));
+ double newmax= pow(10.0, floor(log(value)/M_LN10));
if(newmax*5.0 <= max && newmax*5.0 <= value)
return newmax*5.0;
@@ -2008,10 +2060,7 @@ void ui_check_but(uiBut *but)
BLI_snprintf(but->drawstr, sizeof(but->drawstr), "%s%s", but->str, new_str);
}
else {
- int prec= (int)but->a2;
- if(prec==0) prec= (but->hardmax < 10.001f) ? 3 : 2;
- else CLAMP(prec, 1, 7);
-
+ const int prec= ui_but_float_precision(but, value);
BLI_snprintf(but->drawstr, sizeof(but->drawstr), "%s%.*f", but->str, prec, value);
}
}
@@ -2029,11 +2078,9 @@ void ui_check_but(uiBut *but)
case LABEL:
if(ui_is_but_float(but)) {
- int prec= (int)but->a2;
+ int prec;
value= ui_get_but_val(but);
- if(prec==0) prec= 3;
- else CLAMP(prec, 1, 7);
-
+ prec= ui_but_float_precision(but, value);
BLI_snprintf(but->drawstr, sizeof(but->drawstr), "%s%.*f", but->str, prec, value);
}
else {
diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c
index f9c97c36bdd..c7f11116834 100644
--- a/source/blender/editors/interface/interface_draw.c
+++ b/source/blender/editors/interface/interface_draw.c
@@ -471,6 +471,9 @@ void uiEmboss(float x1, float y1, float x2, float y2, int sel)
void ui_draw_but_IMAGE(ARegion *UNUSED(ar), uiBut *UNUSED(but), uiWidgetColors *UNUSED(wcol), rcti *rect)
{
+#ifdef WITH_HEADLESS
+ (void)rect;
+#else
extern char datatoc_splash_png[];
extern int datatoc_splash_png_size;
ImBuf *ibuf;
@@ -507,6 +510,7 @@ void ui_draw_but_IMAGE(ARegion *UNUSED(ar), uiBut *UNUSED(but), uiWidgetColors *
*/
IMB_freeImBuf(ibuf);
+#endif
}
#if 0
@@ -1116,7 +1120,7 @@ void ui_draw_but_COLORBAND(uiBut *but, uiWidgetColors *UNUSED(wcol), rcti *rect)
ColorBand *coba;
CBData *cbd;
float x1, y1, sizex, sizey;
- float dx, v3[2], v1[2], v2[2], v1a[2], v2a[2];
+ float v3[2], v1[2], v2[2], v1a[2], v2a[2];
int a;
float pos, colf[4]= {0,0,0,0}; /* initialize incase the colorband isnt valid */
@@ -1127,18 +1131,17 @@ void ui_draw_but_COLORBAND(uiBut *but, uiWidgetColors *UNUSED(wcol), rcti *rect)
y1= rect->ymin;
sizex= rect->xmax-x1;
sizey= rect->ymax-y1;
-
+
/* first background, to show tranparency */
- dx= sizex/12.0f;
- v1[0]= x1;
- for(a=0; a<12; a++) {
- if(a & 1) glColor3f(0.3, 0.3, 0.3); else glColor3f(0.8, 0.8, 0.8);
- glRectf(v1[0], y1, v1[0]+dx, y1+0.5f*sizey);
- if(a & 1) glColor3f(0.8, 0.8, 0.8); else glColor3f(0.3, 0.3, 0.3);
- glRectf(v1[0], y1+0.5f*sizey, v1[0]+dx, y1+sizey);
- v1[0]+= dx;
- }
-
+
+ glColor4ub(UI_TRANSP_DARK, UI_TRANSP_DARK, UI_TRANSP_DARK, 255);
+ glRectf(x1, y1, x1+sizex, y1+sizey);
+ glEnable(GL_POLYGON_STIPPLE);
+ glColor4ub(UI_TRANSP_LIGHT, UI_TRANSP_LIGHT, UI_TRANSP_LIGHT, 255);
+ glPolygonStipple(checker_stipple_sml);
+ glRectf(x1, y1, x1+sizex, y1+sizey);
+ glDisable(GL_POLYGON_STIPPLE);
+
glShadeModel(GL_FLAT);
glEnable(GL_BLEND);
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index 531c9dbf799..99a31e039c8 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -81,6 +81,7 @@ static void ui_add_link(bContext *C, uiBut *from, uiBut *to);
#define BUTTON_TOOLTIP_DELAY 0.500
#define BUTTON_FLASH_DELAY 0.020
+#define MENU_SCROLL_INTERVAL 0.1
#define BUTTON_AUTO_OPEN_THRESH 0.3
#define BUTTON_MOUSE_TOWARDS_THRESH 1.0
@@ -4743,6 +4744,8 @@ static uiBut *ui_but_find_mouse_over(ARegion *ar, int x, int y)
continue;
if(but->flag & UI_HIDDEN)
continue;
+ if(but->flag & UI_SCROLLED)
+ continue;
if(ui_but_contains_pt(but, mx, my))
butover= but;
}
@@ -5572,6 +5575,76 @@ static int ui_mouse_motion_towards_check(uiBlock *block, uiPopupBlockHandle *men
return menu->dotowards;
}
+static char ui_menu_scroll_test(uiBlock *block, int my)
+{
+ if(block->flag & (UI_BLOCK_CLIPTOP|UI_BLOCK_CLIPBOTTOM)) {
+ if(block->flag & UI_BLOCK_CLIPTOP)
+ if(my > block->maxy-14)
+ return 't';
+ if(block->flag & UI_BLOCK_CLIPBOTTOM)
+ if(my < block->miny+14)
+ return 'b';
+ }
+ return 0;
+}
+
+static int ui_menu_scroll(ARegion *ar, uiBlock *block, int my)
+{
+ char test= ui_menu_scroll_test(block, my);
+
+ if(test) {
+ uiBut *b1= block->buttons.first;
+ uiBut *b2= block->buttons.last;
+ uiBut *bnext;
+ uiBut *bprev;
+ int dy= 0;
+
+ /* get first and last visible buttons */
+ while(b1 && ui_but_next(b1) && (b1->flag & UI_SCROLLED))
+ b1= ui_but_next(b1);
+ while(b2 && ui_but_prev(b2) && (b2->flag & UI_SCROLLED))
+ b2= ui_but_prev(b2);
+ /* skips separators */
+ bnext= ui_but_next(b1);
+ bprev= ui_but_prev(b2);
+
+ if(bnext==NULL || bprev==NULL)
+ return 0;
+
+ if(test=='t') {
+ /* bottom button is first button */
+ if(b1->y1 < b2->y1)
+ dy= bnext->y1 - b1->y1;
+ /* bottom button is last button */
+ else
+ dy= bprev->y1 - b2->y1;
+ }
+ else if(test=='b') {
+ /* bottom button is first button */
+ if(b1->y1 < b2->y1)
+ dy= b1->y1 - bnext->y1;
+ /* bottom button is last button */
+ else
+ dy= b2->y1 - bprev->y1;
+ }
+ if(dy) {
+
+ for(b1= block->buttons.first; b1; b1= b1->next) {
+ b1->y1 -= dy;
+ b1->y2 -= dy;
+ }
+ /* set flags again */
+ ui_popup_block_scrolltest(block);
+
+ ED_region_tag_redraw(ar);
+
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
static int ui_handle_menu_event(bContext *C, wmEvent *event, uiPopupBlockHandle *menu, int UNUSED(topmenu))
{
ARegion *ar;
@@ -5603,11 +5676,22 @@ static int ui_handle_menu_event(bContext *C, wmEvent *event, uiPopupBlockHandle
* and don't handle events */
ui_mouse_motion_towards_init(menu, mx, my, 1);
}
- else if(event->type != TIMER) {
+ else if(event->type == TIMER) {
+ if(event->customdata == menu->scrolltimer)
+ ui_menu_scroll(ar, block, my);
+ }
+ else {
/* for ui_mouse_motion_towards_block */
- if(event->type == MOUSEMOVE)
+ if(event->type == MOUSEMOVE) {
ui_mouse_motion_towards_init(menu, mx, my, 0);
-
+
+ /* add menu scroll timer, if needed */
+ if(ui_menu_scroll_test(block, my))
+ if(menu->scrolltimer==NULL)
+ menu->scrolltimer=
+ WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER, MENU_SCROLL_INTERVAL);
+ }
+
/* first block own event func */
if(block->block_event_func && block->block_event_func(C, block, event));
/* events not for active search menu button */
diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c
index 037cc22f879..3bf2a9ddd02 100644
--- a/source/blender/editors/interface/interface_icons.c
+++ b/source/blender/editors/interface/interface_icons.c
@@ -461,6 +461,7 @@ static void vicon_move_down_draw(int x, int y, int w, int h, float UNUSED(alpha)
glDisable(GL_LINE_SMOOTH);
}
+#ifndef WITH_HEADLESS
static void init_brush_icons(void)
{
@@ -588,7 +589,7 @@ static void init_internal_icons(void)
IMB_freeImBuf(bbuf);
}
-
+#endif // WITH_HEADLESS
static void init_iconfile_list(struct ListBase *list)
{
@@ -704,6 +705,7 @@ ListBase *UI_iconfile_list(void)
void UI_icons_free(void)
{
+#ifndef WITH_HEADLESS
if(icongltex.id) {
glDeleteTextures(1, &icongltex.id);
icongltex.id= 0;
@@ -711,6 +713,7 @@ void UI_icons_free(void)
free_iconfile_list(&iconfilelist);
BKE_icons_free();
+#endif
}
void UI_icons_free_drawinfo(void *drawinfo)
@@ -792,10 +795,14 @@ int UI_icon_get_height(int icon_id)
void UI_icons_init(int first_dyn_id)
{
+#ifdef WITH_HEADLESS
+ (void)first_dyn_id;
+#else
init_iconfile_list(&iconfilelist);
BKE_icons_init(first_dyn_id);
init_internal_icons();
init_brush_icons();
+#endif
}
/* Render size for preview images and icons
@@ -945,6 +952,7 @@ static void icon_draw_size(float x, float y, int icon_id, float aspect, float al
Icon *icon = NULL;
DrawInfo *di = NULL;
IconImage *iimg;
+ float fdraw_size= UI_DPI_FAC*draw_size;
int w, h;
icon = BKE_icon_get(icon_id);
@@ -965,8 +973,8 @@ static void icon_draw_size(float x, float y, int icon_id, float aspect, float al
}
/* scale width and height according to aspect */
- w = (int)(draw_size/aspect + 0.5f);
- h = (int)(draw_size/aspect + 0.5f);
+ w = (int)(fdraw_size/aspect + 0.5f);
+ h = (int)(fdraw_size/aspect + 0.5f);
if(di->type == ICON_TYPE_VECTOR) {
/* vector icons use the uiBlock transformation, they are not drawn
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index e95b544d0c0..8475090b468 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -45,6 +45,7 @@ struct uiHandleButtonData;
struct wmEvent;
struct wmOperatorType;
struct wmWindow;
+struct wmTimer;
struct uiStyle;
struct uiWidgetColors;
struct uiLayout;
@@ -107,8 +108,8 @@ typedef enum {
#define UI_PANEL_MINY 70
/* uiBut->flag */
-#define UI_SELECT 1 /* use when the button is pressed */
-/*#define UI_MOUSE_OVER 2*/ /*UNUSED, free flag*/
+#define UI_SELECT 1 /* use when the button is pressed */
+#define UI_SCROLLED 2 /* temp hidden, scrolled away */
#define UI_ACTIVE 4
#define UI_HAS_ICON 8
#define UI_TEXTINPUT 16
@@ -116,8 +117,8 @@ typedef enum {
/* warn: rest of uiBut->flag in UI_interface.h */
/* internal panel drawing defines */
-#define PNL_GRID 4
-#define PNL_HEADER 20
+#define PNL_GRID (UI_UNIT_Y / 5) /* 4 default */
+#define PNL_HEADER UI_UNIT_Y /* 20 default */
/* panel->flag */
#define PNL_SELECT 1
@@ -395,6 +396,8 @@ struct uiPopupBlockHandle {
void (*popup_func)(struct bContext *C, void *arg, int event);
void (*cancel_func)(void *arg);
void *popup_arg;
+
+ struct wmTimer *scrolltimer;
/* for operator popups */
struct wmOperatorType *optype;
@@ -416,9 +419,11 @@ void ui_block_func_ICONTEXTROW(struct bContext *C, uiLayout *layout, void *arg_b
struct ARegion *ui_tooltip_create(struct bContext *C, struct ARegion *butregion, uiBut *but);
void ui_tooltip_free(struct bContext *C, struct ARegion *ar);
-uiBut *ui_popup_menu_memory(uiBlock *block, uiBut *but);
+uiBut *ui_popup_menu_memory(struct uiBlock *block, struct uiBut *but);
+
+float *ui_block_hsv_get(struct uiBlock *block);
+void ui_popup_block_scrolltest(struct uiBlock *block);
-float *ui_block_hsv_get(uiBlock *block);
/* searchbox for string button */
ARegion *ui_searchbox_create(struct bContext *C, struct ARegion *butregion, uiBut *but);
@@ -481,6 +486,11 @@ void ui_widget_color_init(struct ThemeUI *tui);
void ui_draw_menu_item(struct uiFontStyle *fstyle, rcti *rect, const char *name, int iconid, int state);
void ui_draw_preview_item(struct uiFontStyle *fstyle, rcti *rect, const char *name, int iconid, int state);
+extern unsigned char checker_stipple_sml[];
+/* used for transp checkers */
+#define UI_TRANSP_DARK 100
+#define UI_TRANSP_LIGHT 160
+
/* interface_style.c */
void uiStyleInit(void);
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index b68634acd1e..55c1488291b 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -651,6 +651,9 @@ PointerRNA uiItemFullO(uiLayout *layout, const char *opname, const char *name, i
if (flag & UI_ITEM_R_NO_BG)
uiBlockSetEmboss(block, UI_EMBOSS);
+ if(layout->redalert)
+ uiButSetFlag(but, UI_BUT_REDALERT);
+
/* assign properties */
if(properties || (flag & UI_ITEM_O_RETURN_PROPS)) {
PointerRNA *opptr= uiButGetOperatorPtrRNA(but);
diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c
index 6677f2b1bae..9ed3cabb4cb 100644
--- a/source/blender/editors/interface/interface_panel.c
+++ b/source/blender/editors/interface/interface_panel.c
@@ -334,10 +334,13 @@ static void uiPanelPop(uiBlock *UNUSED(block))
void UI_DrawTriIcon(float x, float y, char dir)
{
if(dir=='h') {
- ui_draw_anti_tria( x-3,y-5, x-3,y+5, x+7,y );
+ ui_draw_anti_tria( x-3, y-5, x-3, y+5, x+7,y );
}
- else {
- ui_draw_anti_tria( x-5,y+3, x+5,y+3, x,y-7);
+ else if(dir=='t') {
+ ui_draw_anti_tria( x-5, y-7, x+5, y-7, x, y+3);
+ }
+ else { /* 'v' = vertical, down */
+ ui_draw_anti_tria( x-5, y+3, x+5, y+3, x, y-7);
}
}
@@ -381,7 +384,7 @@ static void ui_draw_x_icon(float x, float y)
}
-#define PNL_ICON 20
+#define PNL_ICON UI_UNIT_X /* could be UI_UNIT_Y too */
static void ui_draw_panel_scalewidget(rcti *rect)
{
diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c
index 8b20406e036..623651083d2 100644
--- a/source/blender/editors/interface/interface_regions.c
+++ b/source/blender/editors/interface/interface_regions.c
@@ -67,7 +67,6 @@
#include "interface_intern.h"
-#define MENU_BUTTON_HEIGHT 20
#define MENU_SEPR_HEIGHT 6
#define B_NOP -1
#define MENU_SHADOW_SIDE 8
@@ -675,7 +674,7 @@ int uiSearchItemAdd(uiSearchItems *items, const char *name, void *poin, int icon
int uiSearchBoxhHeight(void)
{
- return SEARCH_ITEMS*MENU_BUTTON_HEIGHT + 2*MENU_TOP;
+ return SEARCH_ITEMS*UI_UNIT_Y + 2*MENU_TOP;
}
/* ar is the search box itself */
@@ -972,8 +971,6 @@ static void ui_searchbox_region_free_cb(ARegion *ar)
ar->regiondata= NULL;
}
-static void ui_block_position(wmWindow *window, ARegion *butregion, uiBut *but, uiBlock *block);
-
ARegion *ui_searchbox_create(bContext *C, ARegion *butregion, uiBut *but)
{
uiStyle *style= U.uistyles.first; // XXX pass on as arg
@@ -1229,18 +1226,26 @@ static void ui_block_position(wmWindow *window, ARegion *butregion, uiBut *but,
if(but) {
int left=0, right=0, top=0, down=0;
int winx, winy;
- int offscreen;
+ // int offscreen;
wm_window_get_size(window, &winx, &winy);
if(block->direction & UI_CENTER) center= ysize/2;
else center= 0;
-
+
+ /* check if there's space at all */
if( butrct.xmin-xsize > 0.0f) left= 1;
if( butrct.xmax+xsize < winx) right= 1;
if( butrct.ymin-ysize+center > 0.0f) down= 1;
if( butrct.ymax+ysize-center < winy) top= 1;
+ if(top==0 && down==0) {
+ if (butrct.ymin-ysize < winy-butrct.ymax-ysize)
+ top= 1;
+ else
+ down= 1;
+ }
+
dir1= block->direction & UI_DIRECTION;
/* secundary directions */
@@ -1305,7 +1310,7 @@ static void ui_block_position(wmWindow *window, ARegion *butregion, uiBut *but,
if(top==0 && down==0) {
if(dir1==UI_LEFT || dir1==UI_RIGHT) {
// align with bottom of screen
- yof= ysize;
+ // yof= ysize; (not with menu scrolls)
}
}
@@ -1320,15 +1325,16 @@ static void ui_block_position(wmWindow *window, ARegion *butregion, uiBut *but,
// apply requested offset in the block
xof += block->xofs/block->aspect;
yof += block->yofs/block->aspect;
-
+#if 0
/* clamp to window bounds, could be made into an option if its ever annoying */
if( (offscreen= (block->miny+yof)) < 0) yof -= offscreen; /* bottom */
else if((offscreen= (block->maxy+yof)-winy) > 0) yof -= offscreen; /* top */
if( (offscreen= (block->minx+xof)) < 0) xof -= offscreen; /* left */
else if((offscreen= (block->maxx+xof)-winx) > 0) xof -= offscreen; /* right */
+#endif
}
- /* apply */
+ /* apply offset, buttons in window coords */
for(bt= block->buttons.first; bt; bt= bt->next) {
ui_block_to_window_fl(butregion, but->block, &bt->x1, &bt->y1);
@@ -1402,6 +1408,62 @@ static void ui_block_region_draw(const bContext *C, ARegion *ar)
uiDrawBlock(C, block);
}
+static void ui_popup_block_clip(wmWindow *window, uiBlock *block)
+{
+ int winx, winy;
+
+ wm_window_get_size(window, &winx, &winy);
+
+ if(block->minx < MENU_SHADOW_SIDE)
+ block->minx= MENU_SHADOW_SIDE;
+ if(block->maxx > winx-MENU_SHADOW_SIDE)
+ block->maxx= winx-MENU_SHADOW_SIDE;
+
+ if(block->miny < MENU_SHADOW_BOTTOM)
+ block->miny= MENU_SHADOW_BOTTOM;
+ if(block->maxy > winy-MENU_TOP)
+ block->maxy= winy-MENU_TOP;
+}
+
+void ui_popup_block_scrolltest(uiBlock *block)
+{
+ uiBut *bt;
+
+ block->flag &= ~(UI_BLOCK_CLIPBOTTOM|UI_BLOCK_CLIPTOP);
+
+ for(bt= block->buttons.first; bt; bt= bt->next)
+ bt->flag &= ~UI_SCROLLED;
+
+ if(block->buttons.first==block->buttons.last)
+ return;
+
+ /* mark buttons that are outside boundary and the ones next to it for arrow(s) */
+ for(bt= block->buttons.first; bt; bt= bt->next) {
+ if(bt->y1 < block->miny) {
+ bt->flag |= UI_SCROLLED;
+ block->flag |= UI_BLOCK_CLIPBOTTOM;
+ /* make space for arrow */
+ if(bt->y2 < block->miny +10) {
+ if(bt->next && bt->next->y1 > bt->y1)
+ bt->next->flag |= UI_SCROLLED;
+ if(bt->prev && bt->prev->y1 > bt->y1)
+ bt->prev->flag |= UI_SCROLLED;
+ }
+ }
+ if(bt->y2 > block->maxy) {
+ bt->flag |= UI_SCROLLED;
+ block->flag |= UI_BLOCK_CLIPTOP;
+ /* make space for arrow */
+ if(bt->y1 > block->maxy -10) {
+ if(bt->next && bt->next->y2 < bt->y2)
+ bt->next->flag |= UI_SCROLLED;
+ if(bt->prev && bt->prev->y2 < bt->y2)
+ bt->prev->flag |= UI_SCROLLED;
+ }
+ }
+ }
+}
+
uiPopupBlockHandle *ui_popup_block_create(bContext *C, ARegion *butregion, uiBut *but, uiBlockCreateFunc create_func, uiBlockHandleCreateFunc handle_create_func, void *arg)
{
wmWindow *window= CTX_wm_window(C);
@@ -1472,6 +1534,9 @@ uiPopupBlockHandle *ui_popup_block_create(bContext *C, ARegion *butregion, uiBut
block->flag |= UI_BLOCK_POPUP|UI_BLOCK_NUMSELECT;
}
+ /* clip block with window boundary */
+ ui_popup_block_clip(window, block);
+
/* the block and buttons were positioned in window space as in 2.4x, now
* these menu blocks are regions so we bring it back to region space.
* additionally we add some padding for the menu shadow or rounded menus */
@@ -1479,7 +1544,7 @@ uiPopupBlockHandle *ui_popup_block_create(bContext *C, ARegion *butregion, uiBut
ar->winrct.xmax= block->maxx + MENU_SHADOW_SIDE;
ar->winrct.ymin= block->miny - MENU_SHADOW_BOTTOM;
ar->winrct.ymax= block->maxy + MENU_TOP;
-
+
block->minx -= ar->winrct.xmin;
block->maxx -= ar->winrct.xmin;
block->miny -= ar->winrct.ymin;
@@ -1491,12 +1556,15 @@ uiPopupBlockHandle *ui_popup_block_create(bContext *C, ARegion *butregion, uiBut
bt->y1 -= ar->winrct.ymin;
bt->y2 -= ar->winrct.ymin;
}
-
+
block->flag |= UI_BLOCK_LOOP;
/* adds subwindow */
ED_region_init(C, ar);
+ /* checks which buttons are visible, sets flags to prevent draw (do after region init) */
+ ui_popup_block_scrolltest(block);
+
/* get winmat now that we actually have the subwindow */
wmSubWindowSet(window, ar->swinid);
@@ -1511,6 +1579,10 @@ uiPopupBlockHandle *ui_popup_block_create(bContext *C, ARegion *butregion, uiBut
void ui_popup_block_free(bContext *C, uiPopupBlockHandle *handle)
{
ui_remove_temporary_region(C, CTX_wm_screen(C), handle->region);
+
+ if(handle->scrolltimer)
+ WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), handle->scrolltimer);
+
MEM_freeN(handle);
}
@@ -2171,7 +2243,7 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi
the offset is negative because we are inverse moving the
block to be under the mouse */
offset[0]= -(bt->x1 + 0.8f*(bt->x2 - bt->x1));
- offset[1]= -(bt->y1 + 0.5f*MENU_BUTTON_HEIGHT);
+ offset[1]= -(bt->y1 + 0.5f*UI_UNIT_Y);
}
else {
/* position mouse at 0.8*width of the button and below the tile
@@ -2180,7 +2252,7 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi
for(bt=block->buttons.first; bt; bt=bt->next)
offset[0]= MIN2(offset[0], -(bt->x1 + 0.8f*(bt->x2 - bt->x1)));
- offset[1]= 1.5*MENU_BUTTON_HEIGHT;
+ offset[1]= 1.5*UI_UNIT_Y;
}
block->minbounds= minwidth;
@@ -2284,10 +2356,10 @@ uiPopupMenu *uiPupMenuBegin(bContext *C, const char *title, int icon)
if(icon) {
sprintf(titlestr, " %s", title);
- uiDefIconTextBut(pup->block, LABEL, 0, icon, titlestr, 0, 0, 200, MENU_BUTTON_HEIGHT, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefIconTextBut(pup->block, LABEL, 0, icon, titlestr, 0, 0, 200, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
}
else {
- but= uiDefBut(pup->block, LABEL, 0, title, 0, 0, 200, MENU_BUTTON_HEIGHT, NULL, 0.0, 0.0, 0, 0, "");
+ but= uiDefBut(pup->block, LABEL, 0, title, 0, 0, 200, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
but->flag= UI_TEXT_LEFT;
}
}
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index 69e3a1792c6..bbd1bd8773b 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -751,7 +751,7 @@ static uiLayout *draw_modifier(uiLayout *layout, Scene *scene, Object *ob, Modif
if ((ob->type==OB_MESH) && modifier_couldBeCage(scene, md) && (index <= lastCageIndex))
{
/* -- convert to rna ? */
- but = uiDefIconButBitI(block, TOG, eModifierMode_OnCage, 0, ICON_MESH_DATA, 0, 0, 16, 20, &md->mode, 0.0, 0.0, 0.0, 0.0, "Apply modifier to editing cage during Editmode");
+ but = uiDefIconButBitI(block, TOG, eModifierMode_OnCage, 0, ICON_MESH_DATA, 0, 0, UI_UNIT_X-2, UI_UNIT_Y, &md->mode, 0.0, 0.0, 0.0, 0.0, "Apply modifier to editing cage during Editmode");
if (index < cageIndex)
uiButSetFlag(but, UI_BUT_DISABLED);
uiButSetFunc(but, modifiers_setOnCage, ob, md);
@@ -763,7 +763,7 @@ static uiLayout *draw_modifier(uiLayout *layout, Scene *scene, Object *ob, Modif
if (ELEM3(md->type, eModifierType_Hook, eModifierType_Softbody, eModifierType_MeshDeform)) {
/* add disabled pre-tesselated button, so users could have
message for this modifiers */
- but = uiDefIconButBitI(block, TOG, eModifierMode_ApplyOnSpline, 0, ICON_SURFACE_DATA, 0, 0, 16, 20, &md->mode, 0.0, 0.0, 0.0, 0.0, "This modifier could be applied on splines' points only");
+ but = uiDefIconButBitI(block, TOG, eModifierMode_ApplyOnSpline, 0, ICON_SURFACE_DATA, 0, 0, UI_UNIT_X-2, UI_UNIT_Y, &md->mode, 0.0, 0.0, 0.0, 0.0, "This modifier could be applied on splines' points only");
uiButSetFlag(but, UI_BUT_DISABLED);
} else if (mti->type != eModifierTypeType_Constructive) {
/* constructive modifiers tesselates curve before applying */
@@ -1281,31 +1281,32 @@ static void colorband_flip_cb(bContext *C, void *cb_v, void *coba_v)
/* offset aligns from bottom, standard width 300, height 115 */
static void colorband_buttons_large(uiLayout *layout, uiBlock *block, ColorBand *coba, int xoffs, int yoffs, RNAUpdateCb *cb)
{
-
uiBut *bt;
uiLayout *row;
+ const int line1_y= yoffs + 65 + UI_UNIT_Y + 2; /* 2 for some space between the buttons */
+ const int line2_y= yoffs + 65;
if(coba==NULL) return;
- bt= uiDefBut(block, BUT, 0, "Add", 0+xoffs,100+yoffs,40,20, NULL, 0, 0, 0, 0, "Add a new color stop to the colorband");
+ bt= uiDefBut(block, BUT, 0, "Add", 0+xoffs,line1_y,40,UI_UNIT_Y, NULL, 0, 0, 0, 0, "Add a new color stop to the colorband");
uiButSetNFunc(bt, colorband_add_cb, MEM_dupallocN(cb), coba);
- bt= uiDefBut(block, BUT, 0, "Delete", 45+xoffs,100+yoffs,45,20, NULL, 0, 0, 0, 0, "Delete the active position");
+ bt= uiDefBut(block, BUT, 0, "Delete", 45+xoffs,line1_y,45,UI_UNIT_Y, NULL, 0, 0, 0, 0, "Delete the active position");
uiButSetNFunc(bt, colorband_del_cb, MEM_dupallocN(cb), coba);
/* XXX, todo for later - convert to operator - campbell */
- bt= uiDefBut(block, BUT, 0, "F", 95+xoffs,100+yoffs,20,20, NULL, 0, 0, 0, 0, "Flip colorband");
+ bt= uiDefBut(block, BUT, 0, "F", 95+xoffs,line1_y,20,UI_UNIT_Y, NULL, 0, 0, 0, 0, "Flip colorband");
uiButSetNFunc(bt, colorband_flip_cb, MEM_dupallocN(cb), coba);
- uiDefButS(block, NUM, 0, "", 120+xoffs,100+yoffs,80, 20, &coba->cur, 0.0, (float)(MAX2(0, coba->tot-1)), 0, 0, "Choose active color stop");
+ uiDefButS(block, NUM, 0, "", 120+xoffs,line1_y,80, UI_UNIT_Y, &coba->cur, 0.0, (float)(MAX2(0, coba->tot-1)), 0, 0, "Choose active color stop");
bt= uiDefButS(block, MENU, 0, "Interpolation %t|Ease %x1|Cardinal %x3|Linear %x0|B-Spline %x2|Constant %x4",
- 210+xoffs, 100+yoffs, 90, 20, &coba->ipotype, 0.0, 0.0, 0, 0, "Set interpolation between color stops");
+ 210+xoffs, line1_y, 90, UI_UNIT_Y, &coba->ipotype, 0.0, 0.0, 0, 0, "Set interpolation between color stops");
uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
uiBlockEndAlign(block);
- bt= uiDefBut(block, BUT_COLORBAND, 0, "", xoffs,65+yoffs,300,30, coba, 0, 0, 0, 0, "");
+ bt= uiDefBut(block, BUT_COLORBAND, 0, "", xoffs,line2_y,300,UI_UNIT_Y, coba, 0, 0, 0, 0, "");
uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
@@ -1330,11 +1331,11 @@ static void colorband_buttons_small(uiLayout *layout, uiBlock *block, ColorBand
float xs= butr->xmin;
uiBlockBeginAlign(block);
- bt= uiDefBut(block, BUT, 0, "Add", xs,butr->ymin+20.0f,2.0f*unit,20, NULL, 0, 0, 0, 0, "Add a new color stop to the colorband");
+ bt= uiDefBut(block, BUT, 0, "Add", xs,butr->ymin+UI_UNIT_Y,2.0f*unit,UI_UNIT_Y, NULL, 0, 0, 0, 0, "Add a new color stop to the colorband");
uiButSetNFunc(bt, colorband_add_cb, MEM_dupallocN(cb), coba);
- bt= uiDefBut(block, BUT, 0, "Delete", xs+2.0f*unit,butr->ymin+20.0f,1.5f*unit,20, NULL, 0, 0, 0, 0, "Delete the active position");
+ bt= uiDefBut(block, BUT, 0, "Delete", xs+2.0f*unit,butr->ymin+UI_UNIT_Y,1.5f*unit,UI_UNIT_Y, NULL, 0, 0, 0, 0, "Delete the active position");
uiButSetNFunc(bt, colorband_del_cb, MEM_dupallocN(cb), coba);
- bt= uiDefBut(block, BUT, 0, "F", xs+3.5f*unit,butr->ymin+20.0f,0.5f*unit,20, NULL, 0, 0, 0, 0, "Flip the color ramp");
+ bt= uiDefBut(block, BUT, 0, "F", xs+3.5f*unit,butr->ymin+UI_UNIT_Y,0.5f*unit,UI_UNIT_Y, NULL, 0, 0, 0, 0, "Flip the color ramp");
uiButSetNFunc(bt, colorband_flip_cb, MEM_dupallocN(cb), coba);
uiBlockEndAlign(block);
@@ -1346,10 +1347,10 @@ static void colorband_buttons_small(uiLayout *layout, uiBlock *block, ColorBand
}
bt= uiDefButS(block, MENU, 0, "Interpolation %t|Ease %x1|Cardinal %x3|Linear %x0|B-Spline %x2|Constant %x4",
- xs+10.0f*unit, butr->ymin+20.0f, unit*4, 20, &coba->ipotype, 0.0, 0.0, 0, 0, "Set interpolation between color stops");
+ xs+10.0f*unit, butr->ymin+UI_UNIT_Y, unit*4, UI_UNIT_Y, &coba->ipotype, 0.0, 0.0, 0, 0, "Set interpolation between color stops");
uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
- bt= uiDefBut(block, BUT_COLORBAND, 0, "", xs,butr->ymin,butr->xmax-butr->xmin,20.0f, coba, 0, 0, 0, 0, "");
+ bt= uiDefBut(block, BUT_COLORBAND, 0, "", xs,butr->ymin,butr->xmax-butr->xmin,UI_UNIT_Y, coba, 0, 0, 0, 0, "");
uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
uiBlockEndAlign(block);
@@ -1422,7 +1423,7 @@ void uiTemplateHistogram(uiLayout *layout, PointerRNA *ptr, const char *propname
hist = (Histogram *)cptr.data;
- hist->height= (hist->height<=20)?20:hist->height;
+ hist->height= (hist->height<=UI_UNIT_Y)?UI_UNIT_Y:hist->height;
bt= uiDefBut(block, HISTOGRAM, 0, "", rect.xmin, rect.ymin, rect.xmax-rect.xmin, hist->height, hist, 0, 0, 0, 0, "");
uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
@@ -1459,7 +1460,7 @@ void uiTemplateWaveform(uiLayout *layout, PointerRNA *ptr, const char *propname)
block= uiLayoutAbsoluteBlock(layout);
- scopes->wavefrm_height= (scopes->wavefrm_height<=20)?20:scopes->wavefrm_height;
+ scopes->wavefrm_height= (scopes->wavefrm_height<=UI_UNIT_Y)?UI_UNIT_Y:scopes->wavefrm_height;
bt= uiDefBut(block, WAVEFORM, 0, "", rect.xmin, rect.ymin, rect.xmax-rect.xmin, scopes->wavefrm_height, scopes, 0, 0, 0, 0, "");
(void)bt; // UNUSED
@@ -1496,7 +1497,7 @@ void uiTemplateVectorscope(uiLayout *layout, PointerRNA *ptr, const char *propna
block= uiLayoutAbsoluteBlock(layout);
- scopes->vecscope_height= (scopes->vecscope_height<=20)?20:scopes->vecscope_height;
+ scopes->vecscope_height= (scopes->vecscope_height<=UI_UNIT_Y)?UI_UNIT_Y:scopes->vecscope_height;
bt= uiDefBut(block, VECTORSCOPE, 0, "", rect.xmin, rect.ymin, rect.xmax-rect.xmin, scopes->vecscope_height, scopes, 0, 0, 0, 0, "");
uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
@@ -1993,7 +1994,7 @@ void uiTemplateLayers(uiLayout *layout, PointerRNA *ptr, const char *propname,
else if(used_prop && RNA_property_boolean_get_index(used_ptr, used_prop, layer))
icon = ICON_LAYER_USED;
- but= uiDefAutoButR(block, ptr, prop, layer, "", icon, 0, 0, 10, 10);
+ but= uiDefAutoButR(block, ptr, prop, layer, "", icon, 0, 0, UI_UNIT_X/2, UI_UNIT_Y/2);
uiButSetFunc(but, handle_layer_buttons, but, SET_INT_IN_POINTER(layer));
but->type= TOG;
}
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index 58ed1e31b81..b6e255b6758 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -159,6 +159,18 @@ static float check_tria_vert[6][2]= {
static int check_tria_face[4][3]= {
{3, 2, 4}, {3, 4, 5}, {1, 0, 3}, {0, 2, 3}};
+GLubyte checker_stipple_sml[32*32/8] =
+{
+ 255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0, \
+ 255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0, \
+ 0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255, \
+ 0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255, \
+ 255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0, \
+ 255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0, \
+ 0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255, \
+ 0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255, \
+};
+
/* ************************************************* */
void ui_draw_anti_tria(float x1, float y1, float x2, float y2, float x3, float y3)
@@ -614,22 +626,10 @@ static void widgetbase_draw(uiWidgetBase *wtb, uiWidgetColors *wcol)
if(wtb->inner) {
if(wcol->shaded==0) {
if (wcol->alpha_check) {
- GLubyte checker_stipple_sml[32*32/8] =
- {
- 255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0, \
- 255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0, \
- 0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255, \
- 0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255, \
- 255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0, \
- 255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0, \
- 0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255, \
- 0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255, \
- };
-
float x_mid= 0.0f; /* used for dumb clamping of values */
/* dark checkers */
- glColor4ub(100, 100, 100, 255);
+ glColor4ub(UI_TRANSP_DARK, UI_TRANSP_DARK, UI_TRANSP_DARK, 255);
glBegin(GL_POLYGON);
for(a=0; a<wtb->totvert; a++) {
glVertex2fv(wtb->inner_v[a]);
@@ -638,7 +638,7 @@ static void widgetbase_draw(uiWidgetBase *wtb, uiWidgetColors *wcol)
/* light checkers */
glEnable(GL_POLYGON_STIPPLE);
- glColor4ub(160, 160, 160, 255);
+ glColor4ub(UI_TRANSP_LIGHT, UI_TRANSP_LIGHT, UI_TRANSP_LIGHT, 255);
glPolygonStipple(checker_stipple_sml);
glBegin(GL_POLYGON);
for(a=0; a<wtb->totvert; a++) {
@@ -771,7 +771,7 @@ static void widget_draw_preview(BIFIconID icon, float UNUSED(alpha), rcti *rect)
/* icons have been standardized... and this call draws in untransformed coordinates */
-#define ICON_HEIGHT 16.0f
+#define ICON_HEIGHT UI_DPI_FAC*16.0f
static void widget_draw_icon(uiBut *but, BIFIconID icon, float alpha, rcti *rect)
{
@@ -2326,39 +2326,43 @@ static void widget_numslider(uiBut *but, uiWidgetColors *wcol, rcti *rect, int s
wtb.outline= 0;
widgetbase_draw(&wtb, wcol);
- /* slider part */
- VECCOPY(outline, wcol->outline);
- VECCOPY(wcol->outline, wcol->item);
- VECCOPY(wcol->inner, wcol->item);
+ /* draw left/right parts only when not in text editing */
+ if(!(state & UI_TEXTINPUT)) {
+
+ /* slider part */
+ VECCOPY(outline, wcol->outline);
+ VECCOPY(wcol->outline, wcol->item);
+ VECCOPY(wcol->inner, wcol->item);
- if(!(state & UI_SELECT))
- SWAP(short, wcol->shadetop, wcol->shadedown);
-
- rect1= *rect;
-
- value= ui_get_but_val(but);
- fac= ((float)value-but->softmin)*(rect1.xmax - rect1.xmin - offs)/(but->softmax - but->softmin);
-
- /* left part of slider, always rounded */
- rect1.xmax= rect1.xmin + ceil(offs+1.0f);
- round_box_edges(&wtb1, roundboxalign & ~6, &rect1, offs);
- wtb1.outline= 0;
- widgetbase_draw(&wtb1, wcol);
-
- /* right part of slider, interpolate roundness */
- rect1.xmax= rect1.xmin + fac + offs;
- rect1.xmin+= floor(offs-1.0f);
- if(rect1.xmax + offs > rect->xmax)
- offs*= (rect1.xmax + offs - rect->xmax)/offs;
- else
- offs= 0.0f;
- round_box_edges(&wtb1, roundboxalign & ~9, &rect1, offs);
-
- widgetbase_draw(&wtb1, wcol);
- VECCOPY(wcol->outline, outline);
-
- if(!(state & UI_SELECT))
- SWAP(short, wcol->shadetop, wcol->shadedown);
+ if(!(state & UI_SELECT))
+ SWAP(short, wcol->shadetop, wcol->shadedown);
+
+ rect1= *rect;
+
+ value= ui_get_but_val(but);
+ fac= ((float)value-but->softmin)*(rect1.xmax - rect1.xmin - offs)/(but->softmax - but->softmin);
+
+ /* left part of slider, always rounded */
+ rect1.xmax= rect1.xmin + ceil(offs+1.0f);
+ round_box_edges(&wtb1, roundboxalign & ~6, &rect1, offs);
+ wtb1.outline= 0;
+ widgetbase_draw(&wtb1, wcol);
+
+ /* right part of slider, interpolate roundness */
+ rect1.xmax= rect1.xmin + fac + offs;
+ rect1.xmin+= floor(offs-1.0f);
+ if(rect1.xmax + offs > rect->xmax)
+ offs*= (rect1.xmax + offs - rect->xmax)/offs;
+ else
+ offs= 0.0f;
+ round_box_edges(&wtb1, roundboxalign & ~9, &rect1, offs);
+
+ widgetbase_draw(&wtb1, wcol);
+ VECCOPY(wcol->outline, outline);
+
+ if(!(state & UI_SELECT))
+ SWAP(short, wcol->shadetop, wcol->shadedown);
+ }
/* outline */
wtb.outline= 1;
@@ -2597,6 +2601,7 @@ static void widget_box(uiBut *but, uiWidgetColors *wcol, rcti *rect, int UNUSED(
/* store the box bg as gl clearcolor, to retrieve later when drawing semi-transparent rects
* over the top to indicate disabled buttons */
+ /* XXX, this doesnt work right since the color applies to buttons outside the box too. */
glClearColor(wcol->inner[0]/255.0, wcol->inner[1]/255.0, wcol->inner[2]/255.0, 1.0);
VECCOPY(wcol->inner, old_col);
@@ -2872,7 +2877,7 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct
ThemeUI *tui= &btheme->tui;
uiFontStyle *fstyle= &style->widget;
uiWidgetType *wt= NULL;
-
+
/* handle menus separately */
if(but->dt==UI_EMBOSSP) {
switch (but->type) {
@@ -3081,6 +3086,18 @@ void ui_draw_menu_back(uiStyle *UNUSED(style), uiBlock *block, rcti *rect)
else
wt->draw(&wt->wcol, rect, 0, 0);
+ if(block) {
+ if(block->flag & UI_BLOCK_CLIPTOP) {
+ /* XXX no scaling for UI here yet */
+ glColor3ubv((unsigned char*)wt->wcol.text);
+ UI_DrawTriIcon((rect->xmax+rect->xmin)/2, rect->ymax-8, 't');
+ }
+ if(block->flag & UI_BLOCK_CLIPBOTTOM) {
+ /* XXX no scaling for UI here yet */
+ glColor3ubv((unsigned char*)wt->wcol.text);
+ UI_DrawTriIcon((rect->xmax+rect->xmin)/2, rect->ymin+10, 'v');
+ }
+ }
}
void ui_draw_search_back(uiStyle *UNUSED(style), uiBlock *block, rcti *rect)
diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c
index 3564dad474a..bbabe968bb2 100644
--- a/source/blender/editors/interface/resources.c
+++ b/source/blender/editors/interface/resources.c
@@ -585,7 +585,7 @@ void ui_theme_init_default(void)
SETCOL(btheme->tv3d.wire, 0x0, 0x0, 0x0, 255);
SETCOL(btheme->tv3d.lamp, 0, 0, 0, 40);
SETCOL(btheme->tv3d.select, 241, 88, 0, 255);
- SETCOL(btheme->tv3d.active, 255, 140, 25, 255);
+ SETCOL(btheme->tv3d.active, 255, 170, 64, 255);
SETCOL(btheme->tv3d.group, 8, 48, 8, 255);
SETCOL(btheme->tv3d.group_active, 85, 187, 85, 255);
SETCOL(btheme->tv3d.transform, 0xff, 0xff, 0xff, 255);
@@ -604,7 +604,7 @@ void ui_theme_init_default(void)
SETCOL(btheme->tv3d.face_dot, 255, 133, 0, 255);
SETCOL(btheme->tv3d.editmesh_active, 255, 255, 255, 128);
SETCOLF(btheme->tv3d.edge_crease, 0.8, 0, 0.6, 1.0);
- SETCOL(btheme->tv3d.edge_sharp, 255, 32, 32, 255);
+ SETCOL(btheme->tv3d.edge_sharp, 0, 255, 255, 255);
SETCOL(btheme->tv3d.header_text, 0, 0, 0, 255);
SETCOL(btheme->tv3d.header_text_hi, 255, 255, 255, 255);
SETCOL(btheme->tv3d.button_text, 0, 0, 0, 255);
@@ -1578,6 +1578,8 @@ void init_userdef_do_versions(void)
}
if (U.dragthreshold == 0 )
U.dragthreshold= 5;
+ if (U.widget_unit==0)
+ U.widget_unit= (U.dpi * 20 + 36)/72;
/* funny name, but it is GE stuff, moves userdef stuff to engine */
// XXX space_set_commmandline_options();
diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c
index f7bff168a33..434334258af 100644
--- a/source/blender/editors/interface/view2d_ops.c
+++ b/source/blender/editors/interface/view2d_ops.c
@@ -876,6 +876,13 @@ static void view_zoomdrag_exit(bContext *C, wmOperator *op)
}
}
+static int view_zoomdrag_cancel(bContext *C, wmOperator *op)
+{
+ view_zoomdrag_exit(C, op);
+
+ return OPERATOR_CANCELLED;
+}
+
/* for 'redo' only, with no user input */
static int view_zoomdrag_exec(bContext *C, wmOperator *op)
{
@@ -1065,6 +1072,7 @@ static void VIEW2D_OT_zoom(wmOperatorType *ot)
ot->exec= view_zoomdrag_exec;
ot->invoke= view_zoomdrag_invoke;
ot->modal= view_zoomdrag_modal;
+ ot->cancel= view_zoomdrag_cancel;
ot->poll= view_zoom_poll;
@@ -1165,6 +1173,7 @@ static void VIEW2D_OT_zoom_border(wmOperatorType *ot)
ot->invoke= WM_border_select_invoke;
ot->exec= view_borderzoom_exec;
ot->modal= WM_border_select_modal;
+ ot->cancel= WM_border_select_cancel;
ot->poll= view_zoom_poll;
@@ -1352,7 +1361,14 @@ static void scroller_activate_exit(bContext *C, wmOperator *op)
ED_region_tag_redraw(CTX_wm_region(C));
}
-}
+}
+
+static int scroller_activate_cancel(bContext *C, wmOperator *op)
+{
+ scroller_activate_exit(C, op);
+
+ return OPERATOR_CANCELLED;
+}
/* apply transform to view (i.e. adjust 'cur' rect) */
static void scroller_activate_apply(bContext *C, wmOperator *op)
@@ -1561,6 +1577,8 @@ static void VIEW2D_OT_scroller_activate(wmOperatorType *ot)
/* api callbacks */
ot->invoke= scroller_activate_invoke;
ot->modal= scroller_activate_modal;
+ ot->cancel= scroller_activate_cancel;
+
ot->poll= view2d_poll;
}
diff --git a/source/blender/editors/mesh/editmesh_loop.c b/source/blender/editors/mesh/editmesh_loop.c
index d7e59e0a68f..32971ca77ed 100644
--- a/source/blender/editors/mesh/editmesh_loop.c
+++ b/source/blender/editors/mesh/editmesh_loop.c
@@ -716,6 +716,7 @@ void MESH_OT_knife_cut(wmOperatorType *ot)
ot->invoke= WM_gesture_lines_invoke;
ot->modal= WM_gesture_lines_modal;
ot->exec= knife_cut_exec;
+ ot->cancel= WM_gesture_lines_cancel;
ot->poll= EM_view3d_poll;
diff --git a/source/blender/editors/mesh/editmesh_mods.c b/source/blender/editors/mesh/editmesh_mods.c
index b5da36756b5..741cfd7078c 100644
--- a/source/blender/editors/mesh/editmesh_mods.c
+++ b/source/blender/editors/mesh/editmesh_mods.c
@@ -2339,7 +2339,7 @@ int mouse_mesh(bContext *C, const int mval[2], short extend)
if (efa && efa->mat_nr != vc.obedit->actcol-1) {
vc.obedit->actcol= efa->mat_nr+1;
vc.em->mat_nr= efa->mat_nr;
-// BIF_preview_changed(ID_MA);
+ WM_event_add_notifier(C, NC_MATERIAL|ND_SHADING, NULL);
}
WM_event_add_notifier(C, NC_GEOM|ND_SELECT, vc.obedit->data);
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index 424d3dd5a38..bfae101d38e 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -3967,6 +3967,7 @@ short sharesFace(EditMesh *em, EditEdge* e1, EditEdge* e2)
return 0;
}
+#if 0
typedef struct SlideUv {
float origuv[2];
@@ -3980,7 +3981,6 @@ typedef struct SlideVert {
EditVert origvert;
} SlideVert;
-#if 0
int EdgeSlide(EditMesh *em, wmOperator *op, short immediate, float imperc)
{
return 0;
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index c425ef5a36a..c5236a38970 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -174,14 +174,14 @@ void ED_object_add_generic_props(wmOperatorType *ot, int do_editmode)
PropertyRNA *prop;
/* note: this property gets hidden for add-camera operator */
- RNA_def_boolean(ot->srna, "view_align", 0, "Align to View", "Align the new object to the view.");
+ RNA_def_boolean(ot->srna, "view_align", 0, "Align to View", "Align the new object to the view");
if(do_editmode) {
- prop= RNA_def_boolean(ot->srna, "enter_editmode", 0, "Enter Editmode", "Enter editmode when adding this object.");
+ prop= RNA_def_boolean(ot->srna, "enter_editmode", 0, "Enter Editmode", "Enter editmode when adding this object");
RNA_def_property_flag(prop, PROP_HIDDEN);
}
- RNA_def_float_vector_xyz(ot->srna, "location", 3, NULL, -FLT_MAX, FLT_MAX, "Location", "Location for the newly added object.", -FLT_MAX, FLT_MAX);
+ RNA_def_float_vector_xyz(ot->srna, "location", 3, NULL, -FLT_MAX, FLT_MAX, "Location", "Location for the newly added object", -FLT_MAX, FLT_MAX);
RNA_def_float_rotation(ot->srna, "rotation", 3, NULL, -FLT_MAX, FLT_MAX, "Rotation", "Rotation for the newly added object", -FLT_MAX, FLT_MAX);
prop = RNA_def_boolean_layer_member(ot->srna, "layers", 20, NULL, "Layer", "");
@@ -637,7 +637,7 @@ static int object_armature_add_exec(bContext *C, wmOperator *op)
else DAG_id_tag_update(&obedit->id, OB_RECALC_DATA);
if(obedit==NULL) {
- BKE_report(op->reports, RPT_ERROR, "Cannot create editmode armature.");
+ BKE_report(op->reports, RPT_ERROR, "Cannot create editmode armature");
return OPERATOR_CANCELLED;
}
@@ -1382,7 +1382,7 @@ static int convert_exec(bContext *C, wmOperator *op)
void OBJECT_OT_convert(wmOperatorType *ot)
{
/* identifiers */
- ot->name= "Convert";
+ ot->name= "Convert to";
ot->description = "Convert selected objects to another type";
ot->idname= "OBJECT_OT_convert";
@@ -1395,8 +1395,8 @@ void OBJECT_OT_convert(wmOperatorType *ot)
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
/* properties */
- ot->prop= RNA_def_enum(ot->srna, "target", convert_target_items, OB_MESH, "Target", "Type of object to convert to.");
- RNA_def_boolean(ot->srna, "keep_original", 0, "Keep Original", "Keep original objects instead of replacing them.");
+ ot->prop= RNA_def_enum(ot->srna, "target", convert_target_items, OB_MESH, "Target", "Type of object to convert to");
+ RNA_def_boolean(ot->srna, "keep_original", 0, "Keep Original", "Keep original objects instead of replacing them");
}
/**************************** Duplicate ************************/
@@ -1716,7 +1716,7 @@ void OBJECT_OT_duplicate(wmOperatorType *ot)
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
/* to give to transform */
- RNA_def_boolean(ot->srna, "linked", 0, "Linked", "Duplicate object but not object data, linking to the original data.");
+ RNA_def_boolean(ot->srna, "linked", 0, "Linked", "Duplicate object but not object data, linking to the original data");
prop= RNA_def_enum(ot->srna, "mode", transform_mode_types, TFM_TRANSLATION, "Mode", "");
RNA_def_property_flag(prop, PROP_HIDDEN);
}
@@ -1786,8 +1786,8 @@ void OBJECT_OT_add_named(wmOperatorType *ot)
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
- RNA_def_boolean(ot->srna, "linked", 0, "Linked", "Duplicate object but not object data, linking to the original data.");
- RNA_def_string(ot->srna, "name", "Cube", 24, "Name", "Object name to add.");
+ RNA_def_boolean(ot->srna, "linked", 0, "Linked", "Duplicate object but not object data, linking to the original data");
+ RNA_def_string(ot->srna, "name", "Cube", 24, "Name", "Object name to add");
}
@@ -1812,11 +1812,11 @@ static int join_exec(bContext *C, wmOperator *op)
Object *ob= CTX_data_active_object(C);
if(scene->obedit) {
- BKE_report(op->reports, RPT_ERROR, "This data does not support joining in editmode.");
+ BKE_report(op->reports, RPT_ERROR, "This data does not support joining in editmode");
return OPERATOR_CANCELLED;
}
else if(object_data_is_libdata(ob)) {
- BKE_report(op->reports, RPT_ERROR, "Can't edit external libdata.");
+ BKE_report(op->reports, RPT_ERROR, "Can't edit external libdata");
return OPERATOR_CANCELLED;
}
@@ -1865,11 +1865,11 @@ static int join_shapes_exec(bContext *C, wmOperator *op)
Object *ob= CTX_data_active_object(C);
if(scene->obedit) {
- BKE_report(op->reports, RPT_ERROR, "This data does not support joining in editmode.");
+ BKE_report(op->reports, RPT_ERROR, "This data does not support joining in editmode");
return OPERATOR_CANCELLED;
}
else if(object_data_is_libdata(ob)) {
- BKE_report(op->reports, RPT_ERROR, "Can't edit external libdata.");
+ BKE_report(op->reports, RPT_ERROR, "Can't edit external libdata");
return OPERATOR_CANCELLED;
}
diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c
index b513bab3924..565c5810cff 100644
--- a/source/blender/editors/object/object_bake.c
+++ b/source/blender/editors/object/object_bake.c
@@ -22,7 +22,8 @@
*
* The Original Code is: all of this file.
*
- * Contributor(s): none yet.
+ * Contributor(s): Morten Mikkelsen,
+ * Sergey Sharybin
*
* ***** END GPL LICENSE BLOCK *****
*/
@@ -44,10 +45,15 @@
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
#include "DNA_world_types.h"
+#include "DNA_object_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
#include "BLI_blenlib.h"
#include "BLI_threads.h"
#include "BLI_utildefines.h"
+#include "BLI_math.h"
+#include "BLI_math_geom.h"
#include "BKE_blender.h"
#include "BKE_context.h"
@@ -56,6 +62,10 @@
#include "BKE_main.h"
#include "BKE_multires.h"
#include "BKE_report.h"
+#include "BKE_cdderivedmesh.h"
+#include "BKE_modifier.h"
+#include "BKE_DerivedMesh.h"
+#include "BKE_subsurf.h"
#include "RE_pipeline.h"
#include "RE_shader_ext.h"
@@ -74,6 +84,1134 @@
#include "object_intern.h"
+/* ****************** multires BAKING ********************** */
+
+/* holder of per-object data needed for bake job
+ needed to make job totally thread-safe */
+typedef struct MultiresBakerJobData {
+ struct MultiresBakerJobData *next, *prev;
+ DerivedMesh *lores_dm, *hires_dm;
+ int simple, lvl, tot_lvl;
+} MultiresBakerJobData;
+
+/* data passing to multires-baker job */
+typedef struct {
+ ListBase data;
+ int bake_clear, bake_filter;
+ short mode, use_lores_mesh;
+} MultiresBakeJob;
+
+/* data passing to multires baker */
+typedef struct {
+ DerivedMesh *lores_dm, *hires_dm;
+ int simple, lvl, tot_lvl, bake_filter;
+ short mode, use_lores_mesh;
+
+ int tot_obj, tot_image;
+ ListBase image;
+
+ int baked_objects, baked_faces;
+
+ short *stop;
+ short *do_update;
+ float *progress;
+} MultiresBakeRender;
+
+typedef void (*MPassKnownData)(DerivedMesh *lores_dm, DerivedMesh *hires_dm, const void *bake_data,
+ const int face_index, const int lvl, const float st[2],
+ float tangmat[3][3], const int x, const int y);
+
+typedef void* (*MInitBakeData)(MultiresBakeRender *bkr, Image* ima);
+typedef void (*MApplyBakeData)(void *bake_data);
+typedef void (*MFreeBakeData)(void *bake_data);
+
+typedef struct {
+ MVert *mvert;
+ MFace *mface;
+ MTFace *mtface;
+ float *pvtangent;
+ float *precomputed_normals;
+ int w, h;
+ int face_index;
+ int i0, i1, i2;
+ DerivedMesh *lores_dm, *hires_dm;
+ int lvl;
+ void *bake_data;
+ MPassKnownData pass_data;
+} MResolvePixelData;
+
+typedef void (*MFlushPixel)(const MResolvePixelData *data, const int x, const int y);
+
+typedef struct {
+ int w, h;
+ char *texels;
+ const MResolvePixelData *data;
+ MFlushPixel flush_pixel;
+} MBakeRast;
+
+typedef struct {
+ float *heights;
+ float height_min, height_max;
+ Image *ima;
+ DerivedMesh *ssdm;
+} MHeightBakeData;
+
+static void multiresbake_get_normal(const MResolvePixelData *data, float norm[], const int face_num, const int vert_index)
+{
+ unsigned int indices[]= {data->mface[face_num].v1, data->mface[face_num].v2,
+ data->mface[face_num].v3, data->mface[face_num].v4};
+ const int smoothnormal= (data->mface[face_num].flag & ME_SMOOTH);
+
+ if(!smoothnormal) { /* flat */
+ if(data->precomputed_normals) {
+ copy_v3_v3(norm, &data->precomputed_normals[3*face_num]);
+ } else {
+ float nor[3];
+ float *p0, *p1, *p2;
+ const int iGetNrVerts= data->mface[face_num].v4!=0 ? 4 : 3;
+
+ p0= data->mvert[indices[0]].co;
+ p1= data->mvert[indices[1]].co;
+ p2= data->mvert[indices[2]].co;
+
+ if(iGetNrVerts==4) {
+ float *p3= data->mvert[indices[3]].co;
+ normal_quad_v3(nor, p0, p1, p2, p3);
+ } else {
+ normal_tri_v3(nor, p0, p1, p2);
+ }
+
+ copy_v3_v3(norm, nor);
+ }
+ } else {
+ short *no= data->mvert[indices[vert_index]].no;
+
+ normal_short_to_float_v3(norm, no);
+ normalize_v3(norm);
+ }
+}
+
+static void init_bake_rast(MBakeRast *bake_rast, const ImBuf *ibuf, const MResolvePixelData *data, MFlushPixel flush_pixel)
+{
+ memset(bake_rast, 0, sizeof(MBakeRast));
+
+ bake_rast->texels = ibuf->userdata;
+ bake_rast->w= ibuf->x;
+ bake_rast->h= ibuf->y;
+ bake_rast->data= data;
+ bake_rast->flush_pixel= flush_pixel;
+}
+
+static void flush_pixel(const MResolvePixelData *data, const int x, const int y)
+{
+ float st[2]= {(x+0.5f)/data->w, (y+0.5f)/data->h};
+ float *st0, *st1, *st2;
+ float *tang0, *tang1, *tang2;
+ float no0[3], no1[3], no2[3];
+ float fUV[2], from_tang[3][3], to_tang[3][3];
+ float u, v, w, sign;
+ int r;
+
+ const int i0= data->i0;
+ const int i1= data->i1;
+ const int i2= data->i2;
+
+ st0= data->mtface[data->face_index].uv[i0];
+ st1= data->mtface[data->face_index].uv[i1];
+ st2= data->mtface[data->face_index].uv[i2];
+
+ tang0= data->pvtangent + data->face_index*16 + i0*4;
+ tang1= data->pvtangent + data->face_index*16 + i1*4;
+ tang2= data->pvtangent + data->face_index*16 + i2*4;
+
+ multiresbake_get_normal(data, no0, data->face_index, i0); /* can optimize these 3 into one call */
+ multiresbake_get_normal(data, no1, data->face_index, i1);
+ multiresbake_get_normal(data, no2, data->face_index, i2);
+
+ resolve_tri_uv(fUV, st, st0, st1, st2);
+
+ u= fUV[0];
+ v= fUV[1];
+ w= 1-u-v;
+
+ /* the sign is the same at all face vertices for any non degenerate face.
+ Just in case we clamp the interpolated value though. */
+ sign= (tang0[3]*u + tang1[3]*v + tang2[3]*w)<0 ? (-1.0f) : 1.0f;
+
+ /* this sequence of math is designed specifically as is with great care
+ to be compatible with our shader. Please don't change without good reason. */
+ for(r= 0; r<3; r++) {
+ from_tang[0][r]= tang0[r]*u + tang1[r]*v + tang2[r]*w;
+ from_tang[2][r]= no0[r]*u + no1[r]*v + no2[r]*w;
+ }
+
+ cross_v3_v3v3(from_tang[1], from_tang[2], from_tang[0]); /* B = sign * cross(N, T) */
+ mul_v3_fl(from_tang[1], sign);
+ invert_m3_m3(to_tang, from_tang);
+ /* sequence end */
+
+ data->pass_data(data->lores_dm, data->hires_dm, data->bake_data,
+ data->face_index, data->lvl, st, to_tang, x, y);
+}
+
+static void set_rast_triangle(const MBakeRast *bake_rast, const int x, const int y)
+{
+ const int w= bake_rast->w;
+ const int h= bake_rast->h;
+
+ if(x>=0 && x<w && y>=0 && y<h) {
+ if((bake_rast->texels[y*w+x])==0) {
+ flush_pixel(bake_rast->data, x, y);
+ bake_rast->texels[y*w+x]= FILTER_MASK_USED;
+ }
+ }
+}
+
+static void rasterize_half(const MBakeRast *bake_rast,
+ const float s0_s, const float t0_s, const float s1_s, const float t1_s,
+ const float s0_l, const float t0_l, const float s1_l, const float t1_l,
+ const int y0_in, const int y1_in, const int is_mid_right)
+{
+ const int s_stable= fabsf(t1_s-t0_s)>FLT_EPSILON ? 1 : 0;
+ const int l_stable= fabsf(t1_l-t0_l)>FLT_EPSILON ? 1 : 0;
+ const int w= bake_rast->w;
+ const int h= bake_rast->h;
+ int y, y0, y1;
+
+ if(y1_in<=0 || y0_in>=h)
+ return;
+
+ y0= y0_in<0 ? 0 : y0_in;
+ y1= y1_in>=h ? h : y1_in;
+
+ for(y= y0; y<y1; y++) {
+ /*-b(x-x0) + a(y-y0) = 0 */
+ int iXl, iXr, x;
+ float x_l= s_stable!=0 ? (s0_s + (((s1_s-s0_s)*(y-t0_s))/(t1_s-t0_s))) : s0_s;
+ float x_r= l_stable!=0 ? (s0_l + (((s1_l-s0_l)*(y-t0_l))/(t1_l-t0_l))) : s0_l;
+
+ if(is_mid_right!=0)
+ SWAP(float, x_l, x_r);
+
+ iXl= (int)ceilf(x_l);
+ iXr= (int)ceilf(x_r);
+
+ if(iXr>0 && iXl<w) {
+ iXl= iXl<0?0:iXl;
+ iXr= iXr>=w?w:iXr;
+
+ for(x= iXl; x<iXr; x++)
+ set_rast_triangle(bake_rast, x, y);
+ }
+ }
+}
+
+static void bake_rasterize(const MBakeRast *bake_rast, const float st0_in[2], const float st1_in[2], const float st2_in[2])
+{
+ const int w= bake_rast->w;
+ const int h= bake_rast->h;
+ float slo= st0_in[0]*w - 0.5f;
+ float tlo= st0_in[1]*h - 0.5f;
+ float smi= st1_in[0]*w - 0.5f;
+ float tmi= st1_in[1]*h - 0.5f;
+ float shi= st2_in[0]*w - 0.5f;
+ float thi= st2_in[1]*h - 0.5f;
+ int is_mid_right= 0, ylo, yhi, yhi_beg;
+
+ /* skip degenerates */
+ if((slo==smi && tlo==tmi) || (slo==shi && tlo==thi) || (smi==shi && tmi==thi))
+ return;
+
+ /* sort by T */
+ if(tlo>tmi && tlo>thi) {
+ SWAP(float, shi, slo);
+ SWAP(float, thi, tlo);
+ } else if(tmi>thi) {
+ SWAP(float, shi, smi);
+ SWAP(float, thi, tmi);
+ }
+
+ if(tlo>tmi) {
+ SWAP(float, slo, smi);
+ SWAP(float, tlo, tmi);
+ }
+
+ /* check if mid point is to the left or to the right of the lo-hi edge */
+ is_mid_right= (-(shi-slo)*(tmi-thi) + (thi-tlo)*(smi-shi))>0 ? 1 : 0;
+ ylo= (int) ceilf(tlo);
+ yhi_beg= (int) ceilf(tmi);
+ yhi= (int) ceilf(thi);
+
+ /*if(fTmi>ceilf(fTlo))*/
+ rasterize_half(bake_rast, slo, tlo, smi, tmi, slo, tlo, shi, thi, ylo, yhi_beg, is_mid_right);
+ rasterize_half(bake_rast, smi, tmi, shi, thi, slo, tlo, shi, thi, yhi_beg, yhi, is_mid_right);
+}
+
+static int multiresbake_test_break(MultiresBakeRender *bkr)
+{
+ if(!bkr->stop) {
+ /* this means baker is executed outside from job system */
+ return 0;
+ }
+
+ return G.afbreek;
+}
+
+static void do_multires_bake(MultiresBakeRender *bkr, Image* ima, MPassKnownData passKnownData,
+ MInitBakeData initBakeData, MApplyBakeData applyBakeData, MFreeBakeData freeBakeData)
+{
+ DerivedMesh *dm= bkr->lores_dm;
+ ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
+ const int lvl= bkr->lvl;
+ const int tot_face= dm->getNumFaces(dm);
+ MVert *mvert= dm->getVertArray(dm);
+ MFace *mface= dm->getFaceArray(dm);
+ MTFace *mtface= dm->getFaceDataArray(dm, CD_MTFACE);
+ float *pvtangent= NULL;
+
+ if(CustomData_get_layer_index(&dm->faceData, CD_TANGENT) == -1)
+ DM_add_tangent_layer(dm);
+
+ pvtangent= DM_get_face_data_layer(dm, CD_TANGENT);
+
+ if(tot_face > 0) { /* sanity check */
+ int f= 0;
+ MBakeRast bake_rast;
+ MResolvePixelData data={NULL};
+
+ data.mface= mface;
+ data.mvert= mvert;
+ data.mtface= mtface;
+ data.pvtangent= pvtangent;
+ data.precomputed_normals= dm->getFaceDataArray(dm, CD_NORMAL); /* don't strictly need this */
+ data.w= ibuf->x;
+ data.h= ibuf->y;
+ data.lores_dm= dm;
+ data.hires_dm= bkr->hires_dm;
+ data.lvl= lvl;
+ data.pass_data= passKnownData;
+
+ if(initBakeData)
+ data.bake_data= initBakeData(bkr, ima);
+
+ init_bake_rast(&bake_rast, ibuf, &data, flush_pixel);
+
+ for(f= 0; f<tot_face; f++) {
+ MTFace *mtfate= &mtface[f];
+ int verts[3][2], nr_tris, t;
+
+ if(multiresbake_test_break(bkr))
+ break;
+
+ if(mtfate->tpage!=ima)
+ continue;
+
+ data.face_index= f;
+
+ /* might support other forms of diagonal splits later on such as
+ split by shortest diagonal.*/
+ verts[0][0]=0;
+ verts[1][0]=1;
+ verts[2][0]=2;
+
+ verts[0][1]=0;
+ verts[1][1]=2;
+ verts[2][1]=3;
+
+ nr_tris= mface[f].v4!=0 ? 2 : 1;
+ for(t= 0; t<nr_tris; t++) {
+ data.i0= verts[0][t];
+ data.i1= verts[1][t];
+ data.i2 =verts[2][t];
+
+ bake_rasterize(&bake_rast, mtfate->uv[data.i0], mtfate->uv[data.i1], mtfate->uv[data.i2]);
+ }
+
+ bkr->baked_faces++;
+
+ if(bkr->do_update)
+ *bkr->do_update= 1;
+
+ if(bkr->progress)
+ *bkr->progress= ((float)bkr->baked_objects + (float)bkr->baked_faces / tot_face) / bkr->tot_obj;
+ }
+
+ if(applyBakeData)
+ applyBakeData(data.bake_data);
+
+ if(freeBakeData)
+ freeBakeData(data.bake_data);
+ }
+}
+
+static void interp_bilinear_quad_data(float data[4][3], float u, float v, float res[3])
+{
+ float vec[3];
+
+ copy_v3_v3(res, data[0]);
+ mul_v3_fl(res, (1-u)*(1-v));
+ copy_v3_v3(vec, data[1]);
+ mul_v3_fl(vec, u*(1-v)); add_v3_v3(res, vec);
+ copy_v3_v3(vec, data[2]);
+ mul_v3_fl(vec, u*v); add_v3_v3(res, vec);
+ copy_v3_v3(vec, data[3]);
+ mul_v3_fl(vec, (1-u)*v); add_v3_v3(res, vec);
+}
+
+static void interp_barycentric_tri_data(float data[3][3], float u, float v, float res[3])
+{
+ float vec[3];
+
+ copy_v3_v3(res, data[0]);
+ mul_v3_fl(res, u);
+ copy_v3_v3(vec, data[1]);
+ mul_v3_fl(vec, v); add_v3_v3(res, vec);
+ copy_v3_v3(vec, data[2]);
+ mul_v3_fl(vec, 1.0f-u-v); add_v3_v3(res, vec);
+}
+
+/* mode = 0: interpolate normals,
+ mode = 1: interpolate coord */
+static void interp_bilinear_grid(DMGridData *grid, int grid_size, float crn_x, float crn_y, int mode, float res[3])
+{
+ int x0, x1, y0, y1;
+ float u, v;
+ float data[4][3];
+
+ x0= (int) crn_x;
+ x1= x0>=(grid_size-1) ? (grid_size-1) : (x0+1);
+
+ y0= (int) crn_y;
+ y1= y0>=(grid_size-1) ? (grid_size-1) : (y0+1);
+
+ u= crn_x-x0;
+ v= crn_y-y0;
+
+ if(mode == 0) {
+ copy_v3_v3(data[0], grid[y0 * grid_size + x0].no);
+ copy_v3_v3(data[1], grid[y0 * grid_size + x1].no);
+ copy_v3_v3(data[2], grid[y1 * grid_size + x1].no);
+ copy_v3_v3(data[3], grid[y1 * grid_size + x0].no);
+ } else {
+ copy_v3_v3(data[0], grid[y0 * grid_size + x0].co);
+ copy_v3_v3(data[1], grid[y0 * grid_size + x1].co);
+ copy_v3_v3(data[2], grid[y1 * grid_size + x1].co);
+ copy_v3_v3(data[3], grid[y1 * grid_size + x0].co);
+ }
+
+ interp_bilinear_quad_data(data, u, v, res);
+}
+
+static void get_ccgdm_data(DerivedMesh *lodm, DerivedMesh *hidm, const int lvl, const int face_index, const float u, const float v, float co[3], float n[3])
+{
+ MFace mface;
+ DMGridData **grid_data;
+ float crn_x, crn_y;
+ int grid_size, S, face_side;
+ int *grid_offset, g_index;
+
+ lodm->getFace(lodm, face_index, &mface);
+
+ grid_size= hidm->getGridSize(hidm);
+ grid_data= hidm->getGridData(hidm);
+ grid_offset= hidm->getGridOffset(hidm);
+
+ face_side= (grid_size<<1)-1;
+
+ if(lvl==0) {
+ g_index= grid_offset[face_index];
+ S= mdisp_rot_face_to_crn(mface.v4 ? 4 : 3, face_side, u*(face_side-1), v*(face_side-1), &crn_x, &crn_y);
+ } else {
+ const int *index= lodm->getFaceDataArray(lodm, CD_ORIGINDEX);
+ int side= (1 << (lvl-1)) + 1;
+ int grid_index= index[face_index];
+ int loc_offs= face_index % (1<<(2*lvl));
+ int cell_index= loc_offs % ((side-1)*(side-1));
+ int cell_side= grid_size / (side-1);
+ int row= cell_index / (side-1);
+ int col= cell_index % (side-1);
+
+ S= face_index / (1<<(2*(lvl-1))) - grid_offset[grid_index];
+ g_index= grid_offset[grid_index];
+
+ crn_y= (row * cell_side) + u * cell_side;
+ crn_x= (col * cell_side) + v * cell_side;
+ }
+
+ CLAMP(crn_x, 0.0f, grid_size);
+ CLAMP(crn_y, 0.0f, grid_size);
+
+ if(n != NULL)
+ interp_bilinear_grid(grid_data[g_index + S], grid_size, crn_x, crn_y, 0, n);
+
+ if(co != NULL)
+ interp_bilinear_grid(grid_data[g_index + S], grid_size, crn_x, crn_y, 1, co);
+}
+
+/* mode = 0: interpolate normals,
+ mode = 1: interpolate coord */
+static void interp_bilinear_mface(DerivedMesh *dm, MFace *mface, const float u, const float v, const int mode, float res[3])
+{
+ float data[4][3];
+
+ if(mode == 0) {
+ dm->getVertNo(dm, mface->v1, data[0]);
+ dm->getVertNo(dm, mface->v2, data[1]);
+ dm->getVertNo(dm, mface->v3, data[2]);
+ dm->getVertNo(dm, mface->v4, data[3]);
+ } else {
+ dm->getVertCo(dm, mface->v1, data[0]);
+ dm->getVertCo(dm, mface->v2, data[1]);
+ dm->getVertCo(dm, mface->v3, data[2]);
+ dm->getVertCo(dm, mface->v4, data[3]);
+ }
+
+ interp_bilinear_quad_data(data, u, v, res);
+}
+
+/* mode = 0: interpolate normals,
+ mode = 1: interpolate coord */
+static void interp_barycentric_mface(DerivedMesh *dm, MFace *mface, const float u, const float v, const int mode, float res[3])
+{
+ float data[3][3];
+
+ if(mode == 0) {
+ dm->getVertNo(dm, mface->v1, data[0]);
+ dm->getVertNo(dm, mface->v2, data[1]);
+ dm->getVertNo(dm, mface->v3, data[2]);
+ } else {
+ dm->getVertCo(dm, mface->v1, data[0]);
+ dm->getVertCo(dm, mface->v2, data[1]);
+ dm->getVertCo(dm, mface->v3, data[2]);
+ }
+
+ interp_barycentric_tri_data(data, u, v, res);
+}
+
+static void *init_heights_data(MultiresBakeRender *bkr, Image* ima)
+{
+ MHeightBakeData *height_data;
+ ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
+
+ height_data= MEM_callocN(sizeof(MHeightBakeData), "MultiresBake heightData");
+
+ height_data->ima= ima;
+ height_data->heights= MEM_callocN(sizeof(float)*ibuf->x*ibuf->y, "MultiresBake heights");
+ height_data->height_max= -FLT_MAX;
+ height_data->height_min= FLT_MAX;
+
+ if(!bkr->use_lores_mesh) {
+ SubsurfModifierData smd= {{NULL}};
+ int ss_lvl= bkr->tot_lvl - bkr->lvl;
+
+ CLAMP(ss_lvl, 0, 6);
+
+ smd.levels= smd.renderLevels= ss_lvl;
+ smd.flags|= eSubsurfModifierFlag_SubsurfUv;
+
+ if(bkr->simple)
+ smd.subdivType= ME_SIMPLE_SUBSURF;
+
+ height_data->ssdm= subsurf_make_derived_from_derived(bkr->lores_dm, &smd, 0, NULL, 0, 0, 0);
+ }
+
+ return (void*)height_data;
+}
+
+static void apply_heights_data(void *bake_data)
+{
+ MHeightBakeData *height_data= (MHeightBakeData*)bake_data;
+ ImBuf *ibuf= BKE_image_get_ibuf(height_data->ima, NULL);
+ int x, y, i;
+ float height, *heights= height_data->heights;
+ float min= height_data->height_min, max= height_data->height_max;
+
+ for(x= 0; x<ibuf->x; x++) {
+ for(y =0; y<ibuf->y; y++) {
+ i= ibuf->x*y + x;
+
+ if(((char*)ibuf->userdata)[i] != FILTER_MASK_USED)
+ continue;
+
+ if(ibuf->rect_float) {
+ float *rrgbf= ibuf->rect_float + i*4;
+
+ if(max-min > 1e-5) height= (heights[i]-min)/(max-min);
+ else height= 0;
+
+ rrgbf[0]=rrgbf[1]=rrgbf[2]= height;
+ } else {
+ char *rrgb= (char*)ibuf->rect + i*4;
+
+ if(max-min > 1e-5) height= (heights[i]-min)/(max-min);
+ else height= 0;
+
+ rrgb[0]=rrgb[1]=rrgb[2]= FTOCHAR(height);
+ }
+ }
+ }
+
+ ibuf->userflags= IB_RECT_INVALID;
+}
+
+static void free_heights_data(void *bake_data)
+{
+ MHeightBakeData *height_data= (MHeightBakeData*)bake_data;
+
+ if(height_data->ssdm)
+ height_data->ssdm->release(height_data->ssdm);
+
+ MEM_freeN(height_data->heights);
+ MEM_freeN(height_data);
+}
+
+/* MultiresBake callback for heights baking
+ general idea:
+ - find coord of point with specified UV in hi-res mesh (let's call it p1)
+ - find coord of point and normal with specified UV in lo-res mesh (or subdivided lo-res
+ mesh to make texture smoother) let's call this point p0 and n.
+ - height wound be dot(n, p1-p0) */
+static void apply_heights_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm, const void *bake_data,
+ const int face_index, const int lvl, const float st[2],
+ float UNUSED(tangmat[3][3]), const int x, const int y)
+{
+ MTFace *mtface= CustomData_get_layer(&lores_dm->faceData, CD_MTFACE);
+ MFace mface;
+ Image *ima= mtface[face_index].tpage;
+ ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
+ MHeightBakeData *height_data= (MHeightBakeData*)bake_data;
+ float uv[2], *st0, *st1, *st2, *st3;
+ int pixel= ibuf->x*y + x;
+ float vec[3], p0[3], p1[3], n[3], len;
+
+ lores_dm->getFace(lores_dm, face_index, &mface);
+
+ st0= mtface[face_index].uv[0];
+ st1= mtface[face_index].uv[1];
+ st2= mtface[face_index].uv[2];
+
+ if(mface.v4) {
+ st3= mtface[face_index].uv[3];
+ resolve_quad_uv(uv, st, st0, st1, st2, st3);
+ } else
+ resolve_tri_uv(uv, st, st0, st1, st2);
+
+ CLAMP(uv[0], 0.0f, 1.0f);
+ CLAMP(uv[1], 0.0f, 1.0f);
+
+ get_ccgdm_data(lores_dm, hires_dm, lvl, face_index, uv[0], uv[1], p1, 0);
+
+ if(height_data->ssdm) {
+ //get_ccgdm_data_ss(lores_dm, height_data->ssdm, lvl, face_index, uv[0], uv[1], p0, n);
+ get_ccgdm_data(lores_dm, height_data->ssdm, 0, face_index, uv[0], uv[1], p0, n);
+ } else {
+ MFace mface;
+ lores_dm->getFace(lores_dm, face_index, &mface);
+
+ if(mface.v4) {
+ interp_bilinear_mface(lores_dm, &mface, uv[0], uv[1], 1, p0);
+ interp_bilinear_mface(lores_dm, &mface, uv[0], uv[1], 0, n);
+ } else {
+ interp_barycentric_mface(lores_dm, &mface, uv[0], uv[1], 1, p0);
+ interp_barycentric_mface(lores_dm, &mface, uv[0], uv[1], 0, n);
+ }
+ }
+
+ sub_v3_v3v3(vec, p1, p0);
+ //len= len_v3(vec);
+ len= dot_v3v3(n, vec);
+
+ height_data->heights[pixel]= len;
+ if(len<height_data->height_min) height_data->height_min= len;
+ if(len>height_data->height_max) height_data->height_max= len;
+
+ if(ibuf->rect_float) {
+ float *rrgbf= ibuf->rect_float + pixel*4;
+ rrgbf[3]= 1.0f;
+
+ ibuf->userflags= IB_RECT_INVALID;
+ } else {
+ char *rrgb= (char*)ibuf->rect + pixel*4;
+ rrgb[3]= 255;
+ }
+}
+
+/* MultiresBake callback for normals' baking
+ general idea:
+ - find coord and normal of point with specified UV in hi-res mesh
+ - multiply it by tangmat
+ - vector in color space would be norm(vec) /2 + (0.5, 0.5, 0.5) */
+static void apply_tangmat_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm, const void *UNUSED(bake_data),
+ const int face_index, const int lvl, const float st[2],
+ float tangmat[3][3], const int x, const int y)
+{
+ MTFace *mtface= CustomData_get_layer(&lores_dm->faceData, CD_MTFACE);
+ MFace mface;
+ Image *ima= mtface[face_index].tpage;
+ ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
+ float uv[2], *st0, *st1, *st2, *st3;
+ int pixel= ibuf->x*y + x;
+ float n[3], vec[3], tmp[3]= {0.5, 0.5, 0.5};
+
+ lores_dm->getFace(lores_dm, face_index, &mface);
+
+ st0= mtface[face_index].uv[0];
+ st1= mtface[face_index].uv[1];
+ st2= mtface[face_index].uv[2];
+
+ if(mface.v4) {
+ st3= mtface[face_index].uv[3];
+ resolve_quad_uv(uv, st, st0, st1, st2, st3);
+ } else
+ resolve_tri_uv(uv, st, st0, st1, st2);
+
+ CLAMP(uv[0], 0.0f, 1.0f);
+ CLAMP(uv[1], 0.0f, 1.0f);
+
+ get_ccgdm_data(lores_dm, hires_dm, lvl, face_index, uv[0], uv[1], NULL, n);
+
+ mul_v3_m3v3(vec, tangmat, n);
+ normalize_v3(vec);
+ mul_v3_fl(vec, 0.5);
+ add_v3_v3(vec, tmp);
+
+ if(ibuf->rect_float) {
+ float *rrgbf= ibuf->rect_float + pixel*4;
+ rrgbf[0]= vec[0];
+ rrgbf[1]= vec[1];
+ rrgbf[2]= vec[2];
+ rrgbf[3]= 1.0f;
+
+ ibuf->userflags= IB_RECT_INVALID;
+ } else {
+ char *rrgb= (char*)ibuf->rect + pixel*4;
+ rrgb[0]= FTOCHAR(vec[0]);
+ rrgb[1]= FTOCHAR(vec[1]);
+ rrgb[2]= FTOCHAR(vec[2]);
+ rrgb[3]= 255;
+ }
+}
+
+static void count_images(MultiresBakeRender *bkr)
+{
+ int a, totface;
+ DerivedMesh *dm= bkr->lores_dm;
+ MTFace *mtface= CustomData_get_layer(&dm->faceData, CD_MTFACE);
+
+ bkr->image.first= bkr->image.last= NULL;
+ bkr->tot_image= 0;
+
+ totface= dm->getNumFaces(dm);
+
+ for(a= 0; a<totface; a++)
+ mtface[a].tpage->id.flag&= ~LIB_DOIT;
+
+ for(a= 0; a<totface; a++) {
+ Image *ima= mtface[a].tpage;
+ if((ima->id.flag&LIB_DOIT)==0) {
+ LinkData *data= BLI_genericNodeN(ima);
+ BLI_addtail(&bkr->image, data);
+ bkr->tot_image++;
+ ima->id.flag|= LIB_DOIT;
+ }
+ }
+
+ for(a= 0; a<totface; a++)
+ mtface[a].tpage->id.flag&= ~LIB_DOIT;
+}
+
+static void bake_images(MultiresBakeRender *bkr)
+{
+ LinkData *link;
+
+ for(link= bkr->image.first; link; link= link->next) {
+ Image *ima= (Image*)link->data;
+ ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
+
+ if(ibuf->x>0 && ibuf->y>0) {
+ ibuf->userdata= MEM_callocN(ibuf->y*ibuf->x, "MultiresBake imbuf mask");
+
+ switch(bkr->mode) {
+ case RE_BAKE_NORMALS:
+ do_multires_bake(bkr, ima, apply_tangmat_callback, NULL, NULL, NULL);
+ break;
+ case RE_BAKE_DISPLACEMENT:
+ do_multires_bake(bkr, ima, apply_heights_callback, init_heights_data,
+ apply_heights_data, free_heights_data);
+ break;
+ }
+ }
+
+ ima->id.flag|= LIB_DOIT;
+ }
+}
+
+static void finish_images(MultiresBakeRender *bkr)
+{
+ LinkData *link;
+
+ for(link= bkr->image.first; link; link= link->next) {
+ Image *ima= (Image*)link->data;
+ int i;
+ ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
+
+ if(ibuf->x<=0 || ibuf->y<=0)
+ continue;
+
+ /* Margin */
+ if(bkr->bake_filter) {
+ char *temprect;
+
+ /* extend the mask +2 pixels from the image,
+ * this is so colors dont blend in from outside */
+
+ for(i=0; i<bkr->bake_filter; i++)
+ IMB_mask_filter_extend((char *)ibuf->userdata, ibuf->x, ibuf->y);
+
+ temprect = MEM_dupallocN(ibuf->userdata);
+
+ /* expand twice to clear this many pixels, so they blend back in */
+ IMB_mask_filter_extend(temprect, ibuf->x, ibuf->y);
+ IMB_mask_filter_extend(temprect, ibuf->x, ibuf->y);
+
+ /* clear all pixels in the margin */
+ IMB_mask_clear(ibuf, temprect, FILTER_MASK_MARGIN);
+ MEM_freeN(temprect);
+
+ for(i= 0; i<bkr->bake_filter; i++)
+ IMB_filter_extend(ibuf, (char *)ibuf->userdata);
+ }
+
+ ibuf->userflags|= IB_BITMAPDIRTY;
+ if(ibuf->mipmap[0]) {
+ ibuf->userflags|= IB_MIPMAP_INVALID;
+ imb_freemipmapImBuf(ibuf);
+ }
+
+ if(ibuf->userdata) {
+ MEM_freeN(ibuf->userdata);
+ ibuf->userdata= NULL;
+ }
+ }
+}
+
+static void multiresbake_start(MultiresBakeRender *bkr)
+{
+ count_images(bkr);
+ bake_images(bkr);
+ finish_images(bkr);
+}
+
+static int multiresbake_check(bContext *C, wmOperator *op) {
+ Scene *scene= CTX_data_scene(C);
+ Object *ob;
+ Mesh *me;
+ MultiresModifierData *mmd;
+ int ok= 1, a;
+
+ CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) {
+ ob= base->object;
+
+ if(ob->type != OB_MESH) {
+ BKE_report(op->reports, RPT_ERROR, "Basking of multires data only works with active object which is a mesh");
+
+ ok= 0;
+ break;
+ }
+
+ me= (Mesh*)ob->data;
+ mmd= get_multires_modifier(scene, ob, 0);
+
+ /* Multi-resolution should be and be last in the stack */
+ if(ok && mmd) {
+ ModifierData *md;
+
+ ok= mmd->totlvl>0;
+
+ for(md = (ModifierData*)mmd->modifier.next; md && ok; md = md->next) {
+ if (modifier_isEnabled(scene, md, eModifierMode_Realtime)) {
+ ok= 0;
+ }
+ }
+ } else ok= 0;
+
+ if(!ok) {
+ BKE_report(op->reports, RPT_ERROR, "Multires data baking requires multi-resolution object");
+
+ break;
+ }
+
+ if(!me->mtface) {
+ BKE_report(op->reports, RPT_ERROR, "Mesh should be unwrapped before multires data baking");
+
+ ok= 0;
+ } else {
+ a= me->totface;
+ while (ok && a--) {
+ Image *ima= me->mtface[a].tpage;
+
+ if(!ima) {
+ BKE_report(op->reports, RPT_ERROR, "You should have active texture to use multires baker");
+
+ ok= 0;
+ } else {
+ ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
+
+ if(!ibuf) {
+ BKE_report(op->reports, RPT_ERROR, "Baking should happend to image with image buffer");
+
+ ok= 0;
+ } else {
+ if(ibuf->rect==NULL && ibuf->rect_float==NULL)
+ ok= 0;
+
+ if(ibuf->rect_float && !(ibuf->channels==0 || ibuf->channels==4))
+ ok= 0;
+
+ if(!ok)
+ BKE_report(op->reports, RPT_ERROR, "Baking to unsupported image type");
+ }
+ }
+ }
+ }
+
+ if(!ok)
+ break;
+ }
+ CTX_DATA_END;
+
+ return ok;
+}
+
+static DerivedMesh *multiresbake_create_loresdm(Scene *scene, Object *ob, int *lvl)
+{
+ DerivedMesh *dm;
+ MultiresModifierData *mmd= get_multires_modifier(scene, ob, 0);
+ Mesh *me= (Mesh*)ob->data;
+
+ *lvl= mmd->lvl;
+
+ if(mmd->lvl==0) {
+ DerivedMesh *tmp_dm= CDDM_from_mesh(me, ob);
+ dm= CDDM_copy(tmp_dm);
+ tmp_dm->release(tmp_dm);
+ } else {
+ MultiresModifierData tmp_mmd= *mmd;
+ DerivedMesh *cddm= CDDM_from_mesh(me, ob);
+
+ tmp_mmd.lvl= mmd->lvl;
+ dm= multires_dm_create_from_derived(&tmp_mmd, 1, cddm, ob, 0, 0);
+ cddm->release(cddm);
+ }
+
+ return dm;
+}
+
+static DerivedMesh *multiresbake_create_hiresdm(Scene *scene, Object *ob, int *lvl, int *simple)
+{
+ Mesh *me= (Mesh*)ob->data;
+ MultiresModifierData *mmd= get_multires_modifier(scene, ob, 0);
+ MultiresModifierData tmp_mmd= *mmd;
+ DerivedMesh *cddm= CDDM_from_mesh(me, ob);
+ DerivedMesh *dm;
+
+ *lvl= mmd->totlvl;
+ *simple= mmd->simple;
+
+ tmp_mmd.lvl= mmd->totlvl;
+ dm= multires_dm_create_from_derived(&tmp_mmd, 1, cddm, ob, 0, 0);
+ cddm->release(cddm);
+
+ return dm;
+}
+
+static void clear_images(MTFace *mtface, int totface)
+{
+ int a;
+ float vec[4]= {0.0f, 0.0f, 0.0f, 0.0f};
+
+ for(a= 0; a<totface; a++)
+ mtface[a].tpage->id.flag&= ~LIB_DOIT;
+
+ for(a= 0; a<totface; a++) {
+ Image *ima= mtface[a].tpage;
+
+ if((ima->id.flag&LIB_DOIT)==0) {
+ ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
+
+ IMB_rectfill(ibuf, vec);
+ ima->id.flag|= LIB_DOIT;
+ }
+ }
+
+ for(a= 0; a<totface; a++)
+ mtface[a].tpage->id.flag&= ~LIB_DOIT;
+}
+
+static int multiresbake_image_exec_locked(bContext *C, wmOperator *op)
+{
+ Object *ob;
+ Scene *scene= CTX_data_scene(C);
+
+ if(!multiresbake_check(C, op))
+ return OPERATOR_CANCELLED;
+
+ if(scene->r.bake_flag&R_BAKE_CLEAR) { /* clear images */
+ CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) {
+ Mesh *me;
+
+ ob= base->object;
+ me= (Mesh*)ob->data;
+
+ clear_images(me->mtface, me->totface);
+ }
+ CTX_DATA_END;
+ }
+
+ CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) {
+ MultiresBakeRender bkr= {0};
+
+ ob= base->object;
+
+ /* copy data stored in job descriptor */
+ bkr.bake_filter= scene->r.bake_filter;
+ bkr.mode= scene->r.bake_mode;
+ bkr.use_lores_mesh= scene->r.bake_flag&R_BAKE_LORES_MESH;
+
+ /* create low-resolution DM (to bake to) and hi-resolution DM (to bake from) */
+ bkr.lores_dm= multiresbake_create_loresdm(scene, ob, &bkr.lvl);
+ bkr.hires_dm= multiresbake_create_hiresdm(scene, ob, &bkr.tot_lvl, &bkr.simple);
+
+ multiresbake_start(&bkr);
+
+ BLI_freelistN(&bkr.image);
+
+ bkr.lores_dm->release(bkr.lores_dm);
+ bkr.hires_dm->release(bkr.hires_dm);
+ }
+ CTX_DATA_END;
+
+ return OPERATOR_FINISHED;
+}
+
+/* Multiresbake adopted for job-system executing */
+static void init_multiresbake_job(bContext *C, MultiresBakeJob *bkj)
+{
+ Scene *scene= CTX_data_scene(C);
+ Object *ob;
+
+ /* backup scene settings, so their changing in UI would take no effect on baker */
+ bkj->bake_filter= scene->r.bake_filter;
+ bkj->mode= scene->r.bake_mode;
+ bkj->use_lores_mesh= scene->r.bake_flag&R_BAKE_LORES_MESH;
+ bkj->bake_clear= scene->r.bake_flag&R_BAKE_CLEAR;
+
+ CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) {
+ MultiresBakerJobData *data;
+ ob= base->object;
+
+ data= MEM_callocN(sizeof(MultiresBakerJobData), "multiresBaker derivedMesh_data");
+ data->lores_dm = multiresbake_create_loresdm(scene, ob, &data->lvl);
+ data->hires_dm = multiresbake_create_hiresdm(scene, ob, &data->tot_lvl, &data->simple);
+ BLI_addtail(&bkj->data, data);
+ }
+ CTX_DATA_END;
+}
+
+static void multiresbake_startjob(void *bkv, short *stop, short *do_update, float *progress)
+{
+ MultiresBakerJobData *data;
+ MultiresBakeJob *bkj= bkv;
+ int baked_objects= 0, tot_obj;
+
+ tot_obj= BLI_countlist(&bkj->data);
+
+ if(bkj->bake_clear) { /* clear images */
+ for(data= bkj->data.first; data; data= data->next) {
+ DerivedMesh *dm= data->lores_dm;
+ MTFace *mtface= CustomData_get_layer(&dm->faceData, CD_MTFACE);
+
+ clear_images(mtface, dm->getNumFaces(dm));
+ }
+ }
+
+ for(data= bkj->data.first; data; data= data->next) {
+ MultiresBakeRender bkr= {0};
+
+ /* copy data stored in job descriptor */
+ bkr.bake_filter= bkj->bake_filter;
+ bkr.mode= bkj->mode;
+ bkr.use_lores_mesh= bkj->use_lores_mesh;
+
+ /* create low-resolution DM (to bake to) and hi-resolution DM (to bake from) */
+ bkr.lores_dm= data->lores_dm;
+ bkr.hires_dm= data->hires_dm;
+ bkr.tot_lvl= data->tot_lvl;
+ bkr.lvl= data->lvl;
+ bkr.simple= data->simple;
+
+ /* needed for proper progress bar */
+ bkr.tot_obj= tot_obj;
+ bkr.baked_objects= baked_objects;
+
+ bkr.stop= stop;
+ bkr.do_update= do_update;
+ bkr.progress= progress;
+
+ multiresbake_start(&bkr);
+
+ BLI_freelistN(&bkr.image);
+
+ baked_objects++;
+ }
+}
+
+static void multiresbake_freejob(void *bkv)
+{
+ MultiresBakeJob *bkj= bkv;
+ MultiresBakerJobData *data, *next;
+
+ data= bkj->data.first;
+ while (data) {
+ next= data->next;
+ data->lores_dm->release(data->lores_dm);
+ data->hires_dm->release(data->hires_dm);
+ MEM_freeN(data);
+ data= next;
+ }
+
+ MEM_freeN(bkj);
+}
+
+static int multiresbake_image_exec(bContext *C, wmOperator *op)
+{
+ Scene *scene= CTX_data_scene(C);
+ MultiresBakeJob *bkr;
+ wmJob *steve;
+
+ if(!multiresbake_check(C, op))
+ return OPERATOR_CANCELLED;
+
+ bkr= MEM_callocN(sizeof(MultiresBakeJob), "MultiresBakeJob data");
+ init_multiresbake_job(C, bkr);
+
+ /* setup job */
+ steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, "Multires Bake", WM_JOB_EXCL_RENDER|WM_JOB_PRIORITY|WM_JOB_PROGRESS);
+ WM_jobs_customdata(steve, bkr, multiresbake_freejob);
+ WM_jobs_timer(steve, 0.2, NC_IMAGE, 0); /* TODO - only draw bake image, can we enforce this */
+ WM_jobs_callbacks(steve, multiresbake_startjob, NULL, NULL, NULL);
+
+ G.afbreek= 0;
+
+ WM_jobs_start(CTX_wm_manager(C), steve);
+ WM_cursor_wait(0);
+
+ /* add modal handler for ESC */
+ WM_event_add_modal_handler(C, op);
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
/* ****************** render BAKING ********************** */
/* threaded break test */
@@ -147,9 +1285,6 @@ static void init_bake_internal(BakeRender *bkr, bContext *C)
{
Scene *scene= CTX_data_scene(C);
- /* flush multires changes (for sculpt) */
- multires_force_render_update(CTX_data_active_object(C));
-
/* get editmode results */
ED_object_exit_editmode(C, 0); /* 0 = does not exit editmode */
@@ -273,43 +1408,59 @@ static int objects_bake_render_modal(bContext *C, wmOperator *UNUSED(op), wmEven
return OPERATOR_PASS_THROUGH;
}
+static int is_multires_bake(Scene *scene)
+{
+ if ( ELEM(scene->r.bake_mode, RE_BAKE_NORMALS, RE_BAKE_DISPLACEMENT))
+ return scene->r.bake_flag & R_BAKE_MULTIRES;
+
+ return 0;
+}
+
static int objects_bake_render_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(_event))
{
Scene *scene= CTX_data_scene(C);
+ int result= OPERATOR_CANCELLED;
- /* only one render job at a time */
- if(WM_jobs_test(CTX_wm_manager(C), scene))
- return OPERATOR_CANCELLED;
-
- if(test_bake_internal(C, op->reports)==0) {
- return OPERATOR_CANCELLED;
- }
- else {
- BakeRender *bkr= MEM_callocN(sizeof(BakeRender), "render bake");
- wmJob *steve;
+ if(is_multires_bake(scene)) {
+ result= multiresbake_image_exec(C, op);
+ } else {
+ /* only one render job at a time */
+ if(WM_jobs_test(CTX_wm_manager(C), scene))
+ return OPERATOR_CANCELLED;
+
+ if(test_bake_internal(C, op->reports)==0) {
+ return OPERATOR_CANCELLED;
+ }
+ else {
+ BakeRender *bkr= MEM_callocN(sizeof(BakeRender), "render bake");
+ wmJob *steve;
- init_bake_internal(bkr, C);
- bkr->reports= op->reports;
+ init_bake_internal(bkr, C);
+ bkr->reports= op->reports;
- /* setup job */
- steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, "Texture Bake", WM_JOB_EXCL_RENDER|WM_JOB_PRIORITY|WM_JOB_PROGRESS);
- WM_jobs_customdata(steve, bkr, bake_freejob);
- WM_jobs_timer(steve, 0.2, NC_IMAGE, 0); /* TODO - only draw bake image, can we enforce this */
- WM_jobs_callbacks(steve, bake_startjob, NULL, bake_update, NULL);
+ /* setup job */
+ steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, "Texture Bake", WM_JOB_EXCL_RENDER|WM_JOB_PRIORITY|WM_JOB_PROGRESS);
+ WM_jobs_customdata(steve, bkr, bake_freejob);
+ WM_jobs_timer(steve, 0.2, NC_IMAGE, 0); /* TODO - only draw bake image, can we enforce this */
+ WM_jobs_callbacks(steve, bake_startjob, NULL, bake_update, NULL);
- G.afbreek= 0;
- G.rendering = 1;
+ G.afbreek= 0;
+ G.rendering = 1;
- WM_jobs_start(CTX_wm_manager(C), steve);
+ WM_jobs_start(CTX_wm_manager(C), steve);
- WM_cursor_wait(0);
- WM_event_add_notifier(C, NC_SCENE|ND_RENDER_RESULT, scene);
+ WM_cursor_wait(0);
- /* add modal handler for ESC */
- WM_event_add_modal_handler(C, op);
+ /* add modal handler for ESC */
+ WM_event_add_modal_handler(C, op);
+ }
+
+ result= OPERATOR_RUNNING_MODAL;
}
- return OPERATOR_RUNNING_MODAL;
+ WM_event_add_notifier(C, NC_SCENE|ND_RENDER_RESULT, scene);
+
+ return result;
}
@@ -317,46 +1468,53 @@ static int bake_image_exec(bContext *C, wmOperator *op)
{
Main *bmain= CTX_data_main(C);
Scene *scene= CTX_data_scene(C);
+ int result= OPERATOR_CANCELLED;
+ if(is_multires_bake(scene)) {
+ result= multiresbake_image_exec_locked(C, op);
+ } else {
+ if(test_bake_internal(C, op->reports)==0) {
+ return OPERATOR_CANCELLED;
+ }
+ else {
+ ListBase threads;
+ BakeRender bkr= {NULL};
- if(test_bake_internal(C, op->reports)==0) {
- return OPERATOR_CANCELLED;
- }
- else {
- ListBase threads;
- BakeRender bkr= {NULL};
+ init_bake_internal(&bkr, C);
+ bkr.reports= op->reports;
- init_bake_internal(&bkr, C);
- bkr.reports= op->reports;
+ RE_test_break_cb(bkr.re, NULL, thread_break);
+ G.afbreek= 0; /* blender_test_break uses this global */
- RE_test_break_cb(bkr.re, NULL, thread_break);
- G.afbreek= 0; /* blender_test_break uses this global */
+ RE_Database_Baking(bkr.re, bmain, scene, scene->lay, scene->r.bake_mode, (scene->r.bake_flag & R_BAKE_TO_ACTIVE)? OBACT: NULL);
- RE_Database_Baking(bkr.re, bmain, scene, scene->lay, scene->r.bake_mode, (scene->r.bake_flag & R_BAKE_TO_ACTIVE)? OBACT: NULL);
+ /* baking itself is threaded, cannot use test_break in threads */
+ BLI_init_threads(&threads, do_bake_render, 1);
+ bkr.ready= 0;
+ BLI_insert_thread(&threads, &bkr);
- /* baking itself is threaded, cannot use test_break in threads */
- BLI_init_threads(&threads, do_bake_render, 1);
- bkr.ready= 0;
- BLI_insert_thread(&threads, &bkr);
+ while(bkr.ready==0) {
+ PIL_sleep_ms(50);
+ if(bkr.ready)
+ break;
- while(bkr.ready==0) {
- PIL_sleep_ms(50);
- if(bkr.ready)
- break;
+ /* used to redraw in 2.4x but this is just for exec in 2.5 */
+ if (!G.background)
+ blender_test_break();
+ }
+ BLI_end_threads(&threads);
- /* used to redraw in 2.4x but this is just for exec in 2.5 */
- if (!G.background)
- blender_test_break();
- }
- BLI_end_threads(&threads);
+ if(bkr.tot==0) BKE_report(op->reports, RPT_ERROR, "No valid images found to bake to");
- if(bkr.tot==0) BKE_report(op->reports, RPT_ERROR, "No valid images found to bake to");
+ finish_bake_internal(&bkr);
- finish_bake_internal(&bkr);
+ result= OPERATOR_FINISHED;
+ }
}
WM_event_add_notifier(C, NC_SCENE|ND_RENDER_RESULT, scene);
- return OPERATOR_FINISHED;
+
+ return result;
}
void OBJECT_OT_bake_image(wmOperatorType *ot)
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c
index 5996037cd2d..fca35683c6f 100644
--- a/source/blender/editors/object/object_modifier.c
+++ b/source/blender/editors/object/object_modifier.c
@@ -399,6 +399,13 @@ int ED_object_modifier_convert(ReportList *UNUSED(reports), Main *bmain, Scene *
static int modifier_apply_shape(ReportList *reports, Scene *scene, Object *ob, ModifierData *md)
{
+ ModifierTypeInfo *mti= modifierType_getInfo(md->type);
+
+ if (mti->isDisabled && mti->isDisabled(md, 0)) {
+ BKE_report(reports, RPT_ERROR, "Modifier is disabled, skipping apply");
+ return 0;
+ }
+
if (ob->type==OB_MESH) {
DerivedMesh *dm;
Mesh *me= ob->data;
@@ -442,7 +449,7 @@ static int modifier_apply_obdata(ReportList *reports, Scene *scene, Object *ob,
{
ModifierTypeInfo *mti= modifierType_getInfo(md->type);
- if (!(md->mode&eModifierMode_Realtime) || (mti->isDisabled && mti->isDisabled(md, 0))) {
+ if (mti->isDisabled && mti->isDisabled(md, 0)) {
BKE_report(reports, RPT_ERROR, "Modifier is disabled, skipping apply");
return 0;
}
@@ -484,7 +491,7 @@ static int modifier_apply_obdata(ReportList *reports, Scene *scene, Object *ob,
CustomData_free_layer_active(&me->fdata, CD_MDISPS, me->totface);
}
}
- }
+ }
else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
Curve *cu;
int numVerts;
@@ -530,6 +537,8 @@ static int modifier_apply_obdata(ReportList *reports, Scene *scene, Object *ob,
int ED_object_modifier_apply(ReportList *reports, Scene *scene, Object *ob, ModifierData *md, int mode)
{
+ int prev_mode;
+
if (scene->obedit) {
BKE_report(reports, RPT_ERROR, "Modifiers cannot be applied in editmode");
return 0;
@@ -541,12 +550,20 @@ int ED_object_modifier_apply(ReportList *reports, Scene *scene, Object *ob, Modi
if (md!=ob->modifiers.first)
BKE_report(reports, RPT_INFO, "Applied modifier was not first, result may not be as expected.");
+ /* allow apply of a not-realtime modifier, by first re-enabling realtime. */
+ prev_mode= md->mode;
+ md->mode |= eModifierMode_Realtime;
+
if (mode == MODIFIER_APPLY_SHAPE) {
- if (!modifier_apply_shape(reports, scene, ob, md))
+ if (!modifier_apply_shape(reports, scene, ob, md)) {
+ md->mode= prev_mode;
return 0;
+ }
} else {
- if (!modifier_apply_obdata(reports, scene, ob, md))
+ if (!modifier_apply_obdata(reports, scene, ob, md)) {
+ md->mode= prev_mode;
return 0;
+ }
}
BLI_remlink(&ob->modifiers, md);
@@ -1259,16 +1276,22 @@ static int meshdeform_bind_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
if(mmd->bindcagecos) {
- if(mmd->bindweights) MEM_freeN(mmd->bindweights);
if(mmd->bindcagecos) MEM_freeN(mmd->bindcagecos);
if(mmd->dyngrid) MEM_freeN(mmd->dyngrid);
if(mmd->dyninfluences) MEM_freeN(mmd->dyninfluences);
+ if(mmd->bindinfluences) MEM_freeN(mmd->bindinfluences);
+ if(mmd->bindoffsets) MEM_freeN(mmd->bindoffsets);
if(mmd->dynverts) MEM_freeN(mmd->dynverts);
- mmd->bindweights= NULL;
+ if(mmd->bindweights) MEM_freeN(mmd->bindweights); /* deprecated */
+ if(mmd->bindcos) MEM_freeN(mmd->bindcos); /* deprecated */
+
mmd->bindcagecos= NULL;
mmd->dyngrid= NULL;
mmd->dyninfluences= NULL;
+ mmd->bindoffsets= NULL;
mmd->dynverts= NULL;
+ mmd->bindweights= NULL; /* deprecated */
+ mmd->bindcos= NULL; /* deprecated */
mmd->totvert= 0;
mmd->totcagevert= 0;
mmd->totinfluence= 0;
diff --git a/source/blender/editors/object/object_shapekey.c b/source/blender/editors/object/object_shapekey.c
index 7c59278dcf5..fd2e7fd7c99 100644
--- a/source/blender/editors/object/object_shapekey.c
+++ b/source/blender/editors/object/object_shapekey.c
@@ -203,9 +203,9 @@ static int object_shape_key_mirror(bContext *C, Object *ob)
fp1= ((float *)kb->data) + i1*3;
fp2= ((float *)kb->data) + i2*3;
- VECCOPY(tvec, fp1);
- VECCOPY(fp1, fp2);
- VECCOPY(fp2, tvec);
+ copy_v3_v3(tvec, fp1);
+ copy_v3_v3(fp1, fp2);
+ copy_v3_v3(fp2, tvec);
/* flip x axis */
fp1[0] = -fp1[0];
@@ -217,7 +217,46 @@ static int object_shape_key_mirror(bContext *C, Object *ob)
mesh_octree_table(ob, NULL, NULL, 'e');
}
- /* todo, other types? */
+ else if (ob->type == OB_LATTICE) {
+ Lattice *lt= ob->data;
+ int i1, i2;
+ float *fp1, *fp2;
+ int u, v, w;
+ /* half but found up odd value */
+ const int pntsu_half = (((lt->pntsu / 2) + (lt->pntsu % 2))) ;
+
+ /* currently editmode isnt supported by mesh so
+ * ignore here for now too */
+
+ /* if(lt->editlatt) lt= lt->editlatt->latt; */
+
+ for(w=0; w<lt->pntsw; w++) {
+ for(v=0; v<lt->pntsv; v++) {
+ for(u=0; u<pntsu_half; u++) {
+ int u_inv= (lt->pntsu - 1) - u;
+ float tvec[3];
+ if(u == u_inv) {
+ i1= LT_INDEX(lt, u, v, w);
+ fp1= ((float *)kb->data) + i1*3;
+ fp1[0]= -fp1[0];
+ }
+ else {
+ i1= LT_INDEX(lt, u, v, w);
+ i2= LT_INDEX(lt, u_inv, v, w);
+
+ fp1= ((float *)kb->data) + i1*3;
+ fp2= ((float *)kb->data) + i2*3;
+
+ copy_v3_v3(tvec, fp1);
+ copy_v3_v3(fp1, fp2);
+ copy_v3_v3(fp2, tvec);
+ fp1[0]= -fp1[0];
+ fp2[0]= -fp2[0];
+ }
+ }
+ }
+ }
+ }
MEM_freeN(tag_elem);
}
diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c
index 43448198ae1..52ba9460818 100644
--- a/source/blender/editors/object/object_vgroup.c
+++ b/source/blender/editors/object/object_vgroup.c
@@ -77,6 +77,7 @@
static void vgroup_remap_update_users(Object *ob, int *map);
static void vgroup_delete_edit_mode(Object *ob, bDeformGroup *defgroup);
static void vgroup_delete_object_mode(Object *ob, bDeformGroup *dg);
+static void vgroup_delete_all(Object *ob);
static Lattice *vgroup_edit_lattice(Object *ob)
{
@@ -138,22 +139,30 @@ void ED_vgroup_delete(Object *ob, bDeformGroup *defgroup)
vgroup_delete_object_mode(ob, dg);
}
-void ED_vgroup_data_create(ID *id)
+int ED_vgroup_data_create(ID *id)
{
/* create deform verts */
if(GS(id->name)==ID_ME) {
Mesh *me= (Mesh *)id;
me->dvert= CustomData_add_layer(&me->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, me->totvert);
+ return TRUE;
}
else if(GS(id->name)==ID_LT) {
Lattice *lt= (Lattice *)id;
lt->dvert= MEM_callocN(sizeof(MDeformVert)*lt->pntsu*lt->pntsv*lt->pntsw, "lattice deformVert");
+ return TRUE;
+ }
+ else {
+ return FALSE;
}
}
static int ED_vgroup_give_parray(ID *id, MDeformVert ***dvert_arr, int *dvert_tot)
{
+ *dvert_tot = 0;
+ *dvert_arr = NULL;
+
if(id) {
switch(GS(id->name)) {
case ID_ME:
@@ -166,8 +175,6 @@ static int ED_vgroup_give_parray(ID *id, MDeformVert ***dvert_arr, int *dvert_to
int i;
if (!CustomData_has_layer(&em->vdata, CD_MDEFORMVERT)) {
- *dvert_tot = 0;
- *dvert_arr = NULL;
return 0;
}
@@ -195,8 +202,9 @@ static int ED_vgroup_give_parray(ID *id, MDeformVert ***dvert_arr, int *dvert_to
return 1;
}
- else
+ else {
return 0;
+ }
}
case ID_LT:
{
@@ -222,8 +230,6 @@ static int ED_vgroup_give_parray(ID *id, MDeformVert ***dvert_arr, int *dvert_to
}
}
- *dvert_arr= NULL;
- *dvert_tot= 0;
return 0;
}
@@ -265,13 +271,24 @@ int ED_vgroup_copy_array(Object *ob, Object *ob_from)
int i;
int totdef_from= BLI_countlist(&ob_from->defbase);
int totdef= BLI_countlist(&ob->defbase);
+ short new_vgroup= FALSE;
ED_vgroup_give_parray(ob_from->data, &dvert_array_from, &dvert_tot_from);
ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot);
+ if((dvert_array == NULL) && (dvert_array_from != NULL) && ED_vgroup_data_create(ob->data)) {
+ ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot);
+ new_vgroup= TRUE;
+ }
+
if(ob==ob_from || dvert_tot==0 || (dvert_tot != dvert_tot_from) || dvert_array_from==NULL || dvert_array==NULL) {
if (dvert_array) MEM_freeN(dvert_array);
if (dvert_array_from) MEM_freeN(dvert_array_from);
+
+ if(new_vgroup == TRUE) {
+ /* free the newly added vgroup since it wasn't compatible */
+ vgroup_delete_all(ob);
+ }
return 0;
}
@@ -1015,55 +1032,75 @@ static void vgroup_clean_all(Object *ob, float eul, int keep_single)
if (dvert_array) MEM_freeN(dvert_array);
}
-void ED_vgroup_mirror(Object *ob, int mirror_weights, int flip_vgroups)
+
+static void dvert_mirror_op(MDeformVert *dvert, MDeformVert *dvert_mirr,
+ const char sel, const char sel_mirr,
+ const int *flip_map,
+ const short mirror_weights, const short flip_vgroups)
+{
+ BLI_assert(sel || sel_mirr);
+
+ if(sel_mirr && sel) {
+ /* swap */
+ if(mirror_weights)
+ SWAP(MDeformVert, *dvert, *dvert_mirr);
+ if(flip_vgroups) {
+ defvert_flip(dvert, flip_map);
+ defvert_flip(dvert_mirr, flip_map);
+ }
+ }
+ else {
+ /* dvert should always be the target */
+ if(sel_mirr) {
+ SWAP(MDeformVert *, dvert, dvert_mirr);
+ }
+
+ if(mirror_weights)
+ defvert_copy(dvert, dvert_mirr);
+ if(flip_vgroups) {
+ defvert_flip(dvert, flip_map);
+ }
+ }
+}
+
+void ED_vgroup_mirror(Object *ob, const short mirror_weights, const short flip_vgroups)
{
+#define VGROUP_MIRR_OP dvert_mirror_op(dvert, dvert_mirr, sel, sel_mirr, flip_map, mirror_weights, flip_vgroups)
+
EditVert *eve, *eve_mirr;
MDeformVert *dvert, *dvert_mirr;
+ short sel, sel_mirr;
int *flip_map;
if(mirror_weights==0 && flip_vgroups==0)
return;
+ flip_map= defgroup_flip_map(ob, 0);
+
/* only the active group */
if(ob->type == OB_MESH) {
Mesh *me= ob->data;
EditMesh *em = BKE_mesh_get_editmesh(me);
- EM_cache_x_mirror_vert(ob, em);
- if(!CustomData_has_layer(&em->vdata, CD_MDEFORMVERT))
+ if(!CustomData_has_layer(&em->vdata, CD_MDEFORMVERT)) {
+ MEM_freeN(flip_map);
return;
+ }
- flip_map= defgroup_flip_map(ob, 0);
+ EM_cache_x_mirror_vert(ob, em);
/* Go through the list of editverts and assign them */
for(eve=em->verts.first; eve; eve=eve->next){
if((eve_mirr=eve->tmp.v)) {
- if((eve_mirr->f & SELECT || eve->f & SELECT) && (eve != eve_mirr)) {
+ sel= eve->f & SELECT;
+ sel_mirr= eve_mirr->f & SELECT;
+
+ if((sel || sel_mirr) && (eve != eve_mirr)) {
dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT);
dvert_mirr= CustomData_em_get(&em->vdata, eve_mirr->data, CD_MDEFORMVERT);
if(dvert && dvert_mirr) {
- if(eve_mirr->f & SELECT && eve->f & SELECT) {
- /* swap */
- if(mirror_weights)
- SWAP(MDeformVert, *dvert, *dvert_mirr);
- if(flip_vgroups) {
- defvert_flip(dvert, flip_map);
- defvert_flip(dvert_mirr, flip_map);
- }
- }
- else {
- /* dvert should always be the target */
- if(eve_mirr->f & SELECT) {
- SWAP(MDeformVert *, dvert, dvert_mirr);
- }
-
- if(mirror_weights)
- defvert_copy(dvert, dvert_mirr);
- if(flip_vgroups) {
- defvert_flip(dvert, flip_map);
- }
- }
+ VGROUP_MIRR_OP;
}
}
@@ -1071,10 +1108,58 @@ void ED_vgroup_mirror(Object *ob, int mirror_weights, int flip_vgroups)
}
}
- MEM_freeN(flip_map);
-
BKE_mesh_end_editmesh(me, em);
}
+ else if (ob->type == OB_LATTICE) {
+ Lattice *lt= ob->data;
+ int i1, i2;
+ int u, v, w;
+ int pntsu_half;
+ /* half but found up odd value */
+
+ if(lt->editlatt) lt= lt->editlatt->latt;
+
+ if(lt->pntsu == 1 || lt->dvert == NULL) {
+ MEM_freeN(flip_map);
+ return;
+ }
+
+ /* unlike editmesh we know that by only looping over the first hald of
+ * the 'u' indicies it will cover all points except the middle which is
+ * ok in this case */
+ pntsu_half= lt->pntsu / 2;
+
+ for(w=0; w<lt->pntsw; w++) {
+ for(v=0; v<lt->pntsv; v++) {
+ for(u=0; u<pntsu_half; u++) {
+ int u_inv= (lt->pntsu - 1) - u;
+ if(u != u_inv) {
+ BPoint *bp, *bp_mirr;
+
+ i1= LT_INDEX(lt, u, v, w);
+ i2= LT_INDEX(lt, u_inv, v, w);
+
+ bp= &lt->def[i1];
+ bp_mirr= &lt->def[i2];
+
+ sel= bp->f1 & SELECT;
+ sel_mirr= bp_mirr->f1 & SELECT;
+
+ if(sel || sel_mirr) {
+ dvert= &lt->dvert[i1];
+ dvert_mirr= &lt->dvert[i2];
+
+ VGROUP_MIRR_OP;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ MEM_freeN(flip_map);
+
+#undef VGROUP_MIRR_OP
}
static void vgroup_remap_update_users(Object *ob, int *map)
@@ -1920,17 +2005,25 @@ void OBJECT_OT_vertex_group_copy_to_linked(wmOperatorType *ot)
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
}
-static int vertex_group_copy_to_selected_exec(bContext *C, wmOperator *UNUSED(op))
+static int vertex_group_copy_to_selected_exec(bContext *C, wmOperator *op)
{
Object *obact= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ int change= 0;
+ int fail= 0;
CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects)
{
- if(obact != ob)
- ED_vgroup_copy_array(ob, obact);
+ if(obact != ob) {
+ if(ED_vgroup_copy_array(ob, obact)) change++;
+ else fail++;
+ }
}
CTX_DATA_END;
+ if((change == 0 && fail == 0) || fail) {
+ BKE_reportf(op->reports, RPT_ERROR, "Copy to VGroups to Selected warning done %d, failed %d, object data must have matching indicies", change, fail);
+ }
+
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c
index c5ab840914e..6155929243b 100644
--- a/source/blender/editors/physics/particle_edit.c
+++ b/source/blender/editors/physics/particle_edit.c
@@ -3970,18 +3970,6 @@ int PE_undo_valid(Scene *scene)
return 0;
}
-static void PTCacheUndo_number(Scene *scene, PTCacheEdit *edit, int nr)
-{
- PTCacheUndo *undo;
- int a=1;
-
- for(undo= edit->undo.first; undo; undo= undo->next, a++) {
- if(a==nr) break;
- }
- edit->curundo= undo;
- PE_undo_step(scene, 0);
-}
-
static void PTCacheUndo_clear(PTCacheEdit *edit)
{
PTCacheUndo *undo;
@@ -4007,32 +3995,38 @@ void PE_redo(Scene *scene)
PE_undo_step(scene, -1);
}
-void PE_undo_menu(Scene *scene, Object *ob)
+void PE_undo_number(Scene *scene, int nr)
{
- PTCacheEdit *edit= PE_get_current(scene, ob);
+ PTCacheEdit *edit= PE_get_current(scene, OBACT);
PTCacheUndo *undo;
- DynStr *ds;
- short event=0;
- char *menu;
-
- if(!edit) return;
-
- ds= BLI_dynstr_new();
-
- BLI_dynstr_append(ds, "Particlemode Undo History %t");
+ int a=0;
- for(undo= edit->undo.first; undo; undo= undo->next) {
- BLI_dynstr_append(ds, "|");
- BLI_dynstr_append(ds, undo->name);
+ for(undo= edit->undo.first; undo; undo= undo->next, a++) {
+ if(a==nr) break;
}
+ edit->curundo= undo;
+ PE_undo_step(scene, 0);
+}
+
+
+/* get name of undo item, return null if no item with this index */
+/* if active pointer, set it to 1 if true */
+char *PE_undo_get_name(Scene *scene, int nr, int *active)
+{
+ PTCacheEdit *edit= PE_get_current(scene, OBACT);
+ PTCacheUndo *undo;
- menu= BLI_dynstr_get_cstring(ds);
- BLI_dynstr_free(ds);
-
-// XXX event= pupmenu_col(menu, 20);
- MEM_freeN(menu);
+ if(active) *active= 0;
- if(event>0) PTCacheUndo_number(scene, edit, event);
+ if(edit) {
+ undo= BLI_findlink(&edit->undo, nr);
+ if(undo) {
+ if(active && undo==edit->curundo)
+ *active= 1;
+ return undo->name;
+ }
+ }
+ return NULL;
}
/************************ utilities ******************************/
diff --git a/source/blender/editors/physics/physics_fluid.c b/source/blender/editors/physics/physics_fluid.c
index 4aa9b942cf3..b573c77c7f3 100644
--- a/source/blender/editors/physics/physics_fluid.c
+++ b/source/blender/editors/physics/physics_fluid.c
@@ -56,6 +56,7 @@
#include "DNA_object_fluidsim.h"
#include "BLI_blenlib.h"
+#include "BLI_fileops.h"
#include "BLI_threads.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
@@ -125,7 +126,7 @@ static void get_fluid_gravity(float *gravity, Scene *scene, FluidsimSettings *fs
if (scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY) {
copy_v3_v3(gravity, scene->physics_settings.gravity);
} else {
- copy_v3_v3(gravity, &fss->gravx);
+ copy_v3_v3(gravity, fss->grav);
}
}
@@ -443,7 +444,7 @@ static void fluid_init_all_channels(bContext *C, Object *UNUSED(fsDomain), Fluid
Object *ob = fobj->object;
FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim);
float active= (float)(fluidmd->fss->flag & OB_FLUIDSIM_ACTIVE);
- float rot_d[3], old_rot[3] = {0.f, 0.f, 0.f};
+ float rot_d[3] = {0.f, 0.f, 0.f}, old_rot[3] = {0.f, 0.f, 0.f};
if (ELEM(fluidmd->fss->type, OB_FLUIDSIM_DOMAIN, OB_FLUIDSIM_PARTICLE))
continue;
@@ -809,6 +810,44 @@ static void fluidbake_free_data(FluidAnimChannels *channels, ListBase *fobjects,
}
}
+/* copied from rna_fluidsim.c: fluidsim_find_lastframe() */
+static void fluidsim_delete_until_lastframe(FluidsimSettings *fss)
+{
+ char targetDir[FILE_MAXFILE+FILE_MAXDIR], targetFile[FILE_MAXFILE+FILE_MAXDIR];
+ char targetDirVel[FILE_MAXFILE+FILE_MAXDIR], targetFileVel[FILE_MAXFILE+FILE_MAXDIR];
+ char previewDir[FILE_MAXFILE+FILE_MAXDIR], previewFile[FILE_MAXFILE+FILE_MAXDIR];
+ int curFrame = 1, exists = 0;
+
+ BLI_snprintf(targetDir, sizeof(targetDir), "%sfluidsurface_final_####.bobj.gz", fss->surfdataPath);
+ BLI_snprintf(targetDirVel, sizeof(targetDir), "%sfluidsurface_final_####.bvel.gz", fss->surfdataPath);
+ BLI_snprintf(previewDir, sizeof(targetDir), "%sfluidsurface_preview_####.bobj.gz", fss->surfdataPath);
+
+ BLI_path_abs(targetDir, G.main->name);
+ BLI_path_abs(targetDirVel, G.main->name);
+ BLI_path_abs(previewDir, G.main->name);
+
+ do {
+ BLI_strncpy(targetFile, targetDir, sizeof(targetFile));
+ BLI_strncpy(targetFileVel, targetDirVel, sizeof(targetFileVel));
+ BLI_strncpy(previewFile, previewDir, sizeof(previewFile));
+
+ BLI_path_frame(targetFile, curFrame, 0);
+ BLI_path_frame(targetFileVel, curFrame, 0);
+ BLI_path_frame(previewFile, curFrame, 0);
+
+ curFrame++;
+
+ if((exists = BLI_exist(targetFile)))
+ {
+ BLI_delete(targetFile, 0, 0);
+ BLI_delete(targetFileVel, 0, 0);
+ BLI_delete(previewFile, 0, 0);
+ }
+ } while(exists);
+
+ return;
+}
+
static int fluidsimBake(bContext *C, ReportList *reports, Object *fsDomain)
{
Scene *scene= CTX_data_scene(C);
@@ -878,6 +917,9 @@ static int fluidsimBake(bContext *C, ReportList *reports, Object *fsDomain)
// reset last valid frame
domainSettings->lastgoodframe = -1;
+
+ /* delete old baked files */
+ fluidsim_delete_until_lastframe(domainSettings);
/* rough check of settings... */
if(domainSettings->previewresxyz > domainSettings->resolutionxyz) {
@@ -1018,6 +1060,13 @@ static int fluidsimBake(bContext *C, ReportList *reports, Object *fsDomain)
else if (domainSettings->typeFlags&OB_FSBND_PARTSLIP) fsset->domainobsType = FLUIDSIM_OBSTACLE_PARTSLIP;
else if (domainSettings->typeFlags&OB_FSBND_FREESLIP) fsset->domainobsType = FLUIDSIM_OBSTACLE_FREESLIP;
fsset->domainobsPartslip = domainSettings->partSlipValue;
+
+ /* use domainobsType also for surface generation flag (bit: >=64) */
+ if(domainSettings->typeFlags & OB_FSSG_NOOBS)
+ fsset->mFsSurfGenSetting = FLUIDSIM_FSSG_NOOBS;
+ else
+ fsset->mFsSurfGenSetting = 0; // "normal" mode
+
fsset->generateVertexVectors = (domainSettings->domainNovecgen==0);
// init blender domain transform matrix
diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c
index 6191ec9c035..d4de1386871 100644
--- a/source/blender/editors/render/render_internal.c
+++ b/source/blender/editors/render/render_internal.c
@@ -302,6 +302,9 @@ static void make_renderinfo_string(RenderStats *rs, Scene *scene, char *str)
BLI_timestr(rs->lastframetime, info_time_str);
spos+= sprintf(spos, "Time:%s ", info_time_str);
+ if(rs->curfsa)
+ spos+= sprintf(spos, "| Full Sample %d ", rs->curfsa);
+
if(rs->infostr && rs->infostr[0])
spos+= sprintf(spos, "| %s ", rs->infostr);
diff --git a/source/blender/editors/render/render_view.c b/source/blender/editors/render/render_view.c
index 64a4d47cddc..9dfcde6ed0d 100644
--- a/source/blender/editors/render/render_view.c
+++ b/source/blender/editors/render/render_view.c
@@ -184,8 +184,7 @@ void render_view_open(bContext *C, int mx, int my)
area_was_image = 1;
/* this function returns with changed context */
- ED_screen_full_newspace(C, CTX_wm_area(C), SPACE_IMAGE);
- sa= CTX_wm_area(C);
+ sa= ED_screen_full_newspace(C, CTX_wm_area(C), SPACE_IMAGE);
}
if(!sa) {
diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c
index a1a4f33d008..4d531e78ec0 100644
--- a/source/blender/editors/screen/area.c
+++ b/source/blender/editors/screen/area.c
@@ -650,8 +650,12 @@ static void region_rect_recursive(ScrArea *sa, ARegion *ar, rcti *remainder, int
if(ar->next==NULL && alignment!=RGN_ALIGN_QSPLIT)
alignment= RGN_ALIGN_NONE;
+ /* prefsize, for header we stick to exception */
prefsizex= ar->sizex?ar->sizex:ar->type->prefsizex;
- prefsizey= ar->sizey?ar->sizey:ar->type->prefsizey;
+ if(ar->regiontype==RGN_TYPE_HEADER)
+ prefsizey= ar->type->prefsizey;
+ else
+ prefsizey= ar->sizey?ar->sizey:ar->type->prefsizey;
/* hidden is user flag */
if(ar->flag & RGN_FLAG_HIDDEN);
@@ -811,8 +815,18 @@ static void region_rect_recursive(ScrArea *sa, ARegion *ar, rcti *remainder, int
ar->winrct.xmax= ar->winrct.xmin;
}
/* in end, add azones, where appropriate */
- region_azone_add(sa, ar, alignment);
-
+ if(ar->regiontype == RGN_TYPE_HEADER && ar->winy + 6 > sa->winy) {
+ /* The logic for this is: when the header takes up the full area,
+ * disallow hiding it to view the main window.
+ *
+ * Without this, uou can drag down the file selectors header and hide it
+ * by accident very easily (highly annoying!), the value 6 is arbitrary
+ * but accounts for small common rounding problems when scaling the UI,
+ * must be minimum '4' */
+ }
+ else {
+ region_azone_add(sa, ar, alignment);
+ }
region_rect_recursive(sa, ar->next, remainder, quad);
}
@@ -953,6 +967,9 @@ void ED_area_initialize(wmWindowManager *wm, wmWindow *win, ScrArea *sa)
uiFreeBlocks(NULL, &ar->uiblocks);
}
+ /* rechecks 2d matrix for header on dpi changing, do not do for other regions, it resets view && blocks view2d operator polls (ton) */
+ if(ar->regiontype==RGN_TYPE_HEADER)
+ ar->v2d.flag &= ~V2D_IS_INITIALISED;
}
}
@@ -1121,7 +1138,7 @@ void ED_area_newspace(bContext *C, ScrArea *sa, int type)
/* tell WM to refresh, cursor types etc */
WM_event_add_mousemove(C);
- /*send space change notifyer*/
+ /*send space change notifier*/
WM_event_add_notifier(C, NC_SPACE|ND_SPACE_CHANGED, sa);
ED_area_tag_refresh(sa);
@@ -1148,7 +1165,7 @@ void ED_area_prevspace(bContext *C, ScrArea *sa)
}
ED_area_tag_redraw(sa);
- /*send space change notifyer*/
+ /*send space change notifier*/
WM_event_add_notifier(C, NC_SPACE|ND_SPACE_CHANGED, sa);
}
@@ -1196,7 +1213,7 @@ static void spacefunc(struct bContext *C, void *UNUSED(arg1), void *UNUSED(arg2)
ED_area_newspace(C, CTX_wm_area(C), CTX_wm_area(C)->butspacetype);
ED_area_tag_redraw(CTX_wm_area(C));
- /*send space change notifyer*/
+ /*send space change notifier*/
WM_event_add_notifier(C, NC_SPACE|ND_SPACE_CHANGED, CTX_wm_area(C));
}
@@ -1208,13 +1225,13 @@ int ED_area_header_switchbutton(const bContext *C, uiBlock *block, int yco)
int xco= 8;
but= uiDefIconTextButC(block, ICONTEXTROW, 0, ICON_VIEW3D,
- editortype_pup(), xco, yco, XIC+10, YIC,
+ editortype_pup(), xco, yco, UI_UNIT_X+10, UI_UNIT_Y,
&(sa->butspacetype), 1.0, SPACEICONMAX, 0, 0,
"Displays current editor type. "
"Click for menu of available types");
uiButSetFunc(but, spacefunc, NULL, NULL);
- return xco + XIC + 14;
+ return xco + UI_UNIT_X + 14;
}
int ED_area_header_standardbuttons(const bContext *C, uiBlock *block, int yco)
@@ -1230,21 +1247,21 @@ int ED_area_header_standardbuttons(const bContext *C, uiBlock *block, int yco)
if (sa->flag & HEADER_NO_PULLDOWN) {
uiDefIconButBitS(block, TOG, HEADER_NO_PULLDOWN, 0,
ICON_DISCLOSURE_TRI_RIGHT,
- xco,yco,XIC,YIC-2,
+ xco,yco,UI_UNIT_X,UI_UNIT_Y-2,
&(sa->flag), 0, 0, 0, 0,
"Show pulldown menus");
}
else {
uiDefIconButBitS(block, TOG, HEADER_NO_PULLDOWN, 0,
ICON_DISCLOSURE_TRI_DOWN,
- xco,yco,XIC,YIC-2,
+ xco,yco,UI_UNIT_X,UI_UNIT_Y-2,
&(sa->flag), 0, 0, 0, 0,
"Hide pulldown menus");
}
uiBlockSetEmboss(block, UI_EMBOSS);
- return xco + XIC;
+ return xco + UI_UNIT_X;
}
/************************ standard UI regions ************************/
@@ -1265,11 +1282,11 @@ void ED_region_panels(const bContext *C, ARegion *ar, int vertical, const char *
if(vertical) {
w= v2d->cur.xmax - v2d->cur.xmin;
- em= (ar->type->prefsizex)? 10: 20;
+ em= (ar->type->prefsizex)? UI_UNIT_Y/2: UI_UNIT_Y;
}
else {
w= UI_PANEL_WIDTH;
- em= (ar->type->prefsizex)? 10: 20;
+ em= (ar->type->prefsizex)? UI_UNIT_Y/2: UI_UNIT_Y;
}
x= 0;
@@ -1293,8 +1310,8 @@ void ED_region_panels(const bContext *C, ARegion *ar, int vertical, const char *
panel= uiBeginPanel(sa, ar, block, pt, &open);
/* bad fixed values */
- header= (pt->flag & PNL_NO_HEADER)? 0: 20;
- triangle= 22;
+ header= (pt->flag & PNL_NO_HEADER)? 0: UI_UNIT_Y;
+ triangle= (int)(UI_UNIT_Y * 1.1f);
if(vertical)
y -= header;
@@ -1446,6 +1463,7 @@ void ED_region_header(const bContext *C, ARegion *ar)
HeaderType *ht;
Header header = {NULL};
int maxco, xco, yco;
+ int headery= ED_area_headersize();
/* clear */
UI_ThemeClearColor((ED_screen_area_active(C))?TH_HEADER:TH_HEADERDESEL);
@@ -1455,12 +1473,12 @@ void ED_region_header(const bContext *C, ARegion *ar)
UI_view2d_view_ortho(&ar->v2d);
xco= maxco= 8;
- yco= HEADERY-4;
+ yco= headery-4;
/* draw all headers types */
for(ht= ar->type->headertypes.first; ht; ht= ht->next) {
block= uiBeginBlock(C, ar, ht->idname, UI_EMBOSS);
- layout= uiBlockLayout(block, UI_LAYOUT_HORIZONTAL, UI_LAYOUT_HEADER, xco, yco, HEADERY-6, 1, style);
+ layout= uiBlockLayout(block, UI_LAYOUT_HORIZONTAL, UI_LAYOUT_HEADER, xco, yco, UI_UNIT_Y, 1, style);
if(ht->draw) {
header.type= ht;
@@ -1484,7 +1502,7 @@ void ED_region_header(const bContext *C, ARegion *ar)
}
/* always as last */
- UI_view2d_totRect_set(&ar->v2d, maxco+XIC+80, ar->v2d.tot.ymax-ar->v2d.tot.ymin);
+ UI_view2d_totRect_set(&ar->v2d, maxco+UI_UNIT_X+80, ar->v2d.tot.ymax-ar->v2d.tot.ymin);
/* restore view matrix? */
UI_view2d_view_restore(C);
@@ -1495,3 +1513,8 @@ void ED_region_header_init(ARegion *ar)
UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_HEADER, ar->winx, ar->winy);
}
+/* UI_UNIT_Y is defined as U variable now, depending dpi */
+int ED_area_headersize(void)
+{
+ return UI_UNIT_Y+6;
+}
diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c
index 9bc2b1a402c..721ce823351 100644
--- a/source/blender/editors/screen/screen_edit.c
+++ b/source/blender/editors/screen/screen_edit.c
@@ -671,9 +671,9 @@ static void screen_test_scale(bScreen *sc, int winsizex, int winsizey)
/* test for collapsed areas. This could happen in some blender version... */
/* ton: removed option now, it needs Context... */
- /* make each window at least HEADERY high */
+ /* make each window at least ED_area_headersize() high */
for(sa= sc->areabase.first; sa; sa= sa->next) {
- int headery= HEADERY+1;
+ int headery= ED_area_headersize()+1;
if(sa->v1->vec.y+headery > sa->v2->vec.y) {
/* lower edge */
@@ -1055,6 +1055,18 @@ void ED_screen_draw(wmWindow *win)
win->screen->do_draw= 0;
}
+/* helper call for below, dpi changes headers */
+static void screen_refresh_headersizes(void)
+{
+ const ListBase *lb= BKE_spacetypes_list();
+ SpaceType *st;
+
+ for(st= lb->first; st; st= st->next) {
+ ARegionType *art= BKE_regiontype_from_id(st, RGN_TYPE_HEADER);
+ if(art) art->prefsizey= ED_area_headersize();
+ }
+}
+
/* make this screen usable */
/* for file read and first use, for scaling window, area moves */
void ED_screen_refresh(wmWindowManager *wm, wmWindow *win)
@@ -1076,6 +1088,9 @@ void ED_screen_refresh(wmWindowManager *wm, wmWindow *win)
else
wm_subwindow_position(win, win->screen->mainwin, &winrct);
+ /* header size depends on DPI, let's verify */
+ screen_refresh_headersizes();
+
for(sa= win->screen->areabase.first; sa; sa= sa->next) {
/* set spacetype and region callbacks, calls init() */
/* sets subwindows for regions, adds handlers */
@@ -1498,7 +1513,7 @@ void ED_screen_delete_scene(bContext *C, Scene *scene)
unlink_scene(bmain, scene, newscene);
}
-int ED_screen_full_newspace(bContext *C, ScrArea *sa, int type)
+ScrArea *ED_screen_full_newspace(bContext *C, ScrArea *sa, int type)
{
wmWindow *win= CTX_wm_window(C);
bScreen *screen= CTX_wm_screen(C);
@@ -1523,7 +1538,7 @@ int ED_screen_full_newspace(bContext *C, ScrArea *sa, int type)
ED_area_newspace(C, newsa, type);
- return 1;
+ return newsa;
}
void ED_screen_full_prevspace(bContext *C, ScrArea *sa)
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index f454dd9ce02..68326edfb11 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -627,6 +627,13 @@ static int actionzone_modal(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
+static int actionzone_cancel(bContext *UNUSED(C), wmOperator *op)
+{
+ actionzone_exit(op);
+
+ return OPERATOR_CANCELLED;
+}
+
static void SCREEN_OT_actionzone(wmOperatorType *ot)
{
/* identifiers */
@@ -637,6 +644,7 @@ static void SCREEN_OT_actionzone(wmOperatorType *ot)
ot->invoke= actionzone_invoke;
ot->modal= actionzone_modal;
ot->poll= actionzone_area_poll;
+ ot->cancel= actionzone_cancel;
ot->flag= OPTYPE_BLOCKING;
@@ -759,6 +767,7 @@ static void SCREEN_OT_area_swap(wmOperatorType *ot)
ot->invoke= area_swap_invoke;
ot->modal= area_swap_modal;
ot->poll= ED_operator_areaactive;
+ ot->cancel= area_swap_cancel;
ot->flag= OPTYPE_BLOCKING;
}
@@ -868,13 +877,14 @@ typedef struct sAreaMoveData {
static void area_move_set_limits(bScreen *sc, int dir, int *bigger, int *smaller)
{
ScrArea *sa;
+ int areaminy= ED_area_headersize()+1;
/* we check all areas and test for free space with MINSIZE */
*bigger= *smaller= 100000;
for(sa= sc->areabase.first; sa; sa= sa->next) {
if(dir=='h') {
- int y1= sa->v2->vec.y - sa->v1->vec.y-AREAMINY;
+ int y1= sa->v2->vec.y - sa->v1->vec.y-areaminy;
/* if top or down edge selected, test height */
if(sa->v1->flag && sa->v4->flag)
@@ -933,6 +943,7 @@ static void area_move_apply_do(bContext *C, int origval, int delta, int dir, int
bScreen *sc= CTX_wm_screen(C);
ScrVert *v1;
ScrArea *sa;
+ int areaminy= ED_area_headersize()+1;
delta= CLAMPIS(delta, -smaller, bigger);
@@ -950,8 +961,8 @@ static void area_move_apply_do(bContext *C, int origval, int delta, int dir, int
v1->vec.y-= (v1->vec.y % AREAGRID);
/* prevent too small top header */
- if(v1->vec.y > win->sizey-AREAMINY)
- v1->vec.y= win->sizey-AREAMINY;
+ if(v1->vec.y > win->sizey-areaminy)
+ v1->vec.y= win->sizey-areaminy;
}
}
}
@@ -1165,6 +1176,7 @@ static int area_split_init(bContext *C, wmOperator *op)
{
ScrArea *sa= CTX_wm_area(C);
sAreaSplitData *sd;
+ int areaminy= ED_area_headersize()+1;
int dir;
/* required context */
@@ -1175,7 +1187,7 @@ static int area_split_init(bContext *C, wmOperator *op)
/* minimal size */
if(dir=='v' && sa->winx < 2*AREAMINX) return 0;
- if(dir=='h' && sa->winy < 2*AREAMINY) return 0;
+ if(dir=='h' && sa->winy < 2*areaminy) return 0;
/* custom data */
sd= (sAreaSplitData*)MEM_callocN(sizeof (sAreaSplitData), "op_area_split");
@@ -1491,6 +1503,7 @@ static void SCREEN_OT_area_split(wmOperatorType *ot)
ot->exec= area_split_exec;
ot->invoke= area_split_invoke;
ot->modal= area_split_modal;
+ ot->cancel= area_split_cancel;
ot->poll= screen_active_editable;
ot->flag= OPTYPE_BLOCKING;
@@ -1628,7 +1641,7 @@ static int region_scale_modal(bContext *C, wmOperator *op, wmEvent *event)
rmd->ar->sizex= rmd->origval + delta;
CLAMP(rmd->ar->sizex, 0, rmd->maxsize);
- if(rmd->ar->sizex < 24) {
+ if(rmd->ar->sizex < UI_UNIT_X) {
rmd->ar->sizex= rmd->origval;
if(!(rmd->ar->flag & RGN_FLAG_HIDDEN))
ED_region_toggle_hidden(C, rmd->ar);
@@ -1643,11 +1656,17 @@ static int region_scale_modal(bContext *C, wmOperator *op, wmEvent *event)
rmd->ar->sizey= rmd->origval + delta;
CLAMP(rmd->ar->sizey, 0, rmd->maxsize);
-
- if(rmd->ar->regiontype == RGN_TYPE_TOOL_PROPS)
- maxsize = rmd->maxsize - ((rmd->sa->headertype==2)?48:24) - 10;
- if(rmd->ar->sizey < 24 || (maxsize > 0 && (rmd->ar->sizey > maxsize)) ) {
+ if(rmd->ar->regiontype == RGN_TYPE_TOOL_PROPS) {
+ /* this calculation seems overly verbose
+ * can someone explain why this method is necessary? - campbell */
+ maxsize = rmd->maxsize - ((rmd->sa->headertype==HEADERTOP)?UI_UNIT_Y*2:UI_UNIT_Y) - (UI_UNIT_Y/4);
+ }
+
+ /* note, 'UI_UNIT_Y/4' means you need to drag the header almost
+ * all the way down for it to become hidden, this is done
+ * otherwise its too easy to do this by accident */
+ if(rmd->ar->sizey < UI_UNIT_Y/4 || (maxsize > 0 && (rmd->ar->sizey > maxsize)) ) {
rmd->ar->sizey= rmd->origval;
if(!(rmd->ar->flag & RGN_FLAG_HIDDEN))
ED_region_toggle_hidden(C, rmd->ar);
@@ -1684,6 +1703,13 @@ static int region_scale_modal(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
+int region_scale_cancel(bContext *UNUSED(C), wmOperator *op)
+{
+ MEM_freeN(op->customdata);
+ op->customdata = NULL;
+
+ return OPERATOR_CANCELLED;
+}
static void SCREEN_OT_region_scale(wmOperatorType *ot)
{
@@ -1694,6 +1720,7 @@ static void SCREEN_OT_region_scale(wmOperatorType *ot)
ot->invoke= region_scale_invoke;
ot->modal= region_scale_modal;
+ ot->cancel= region_scale_cancel;
ot->poll= ED_operator_areaactive;
@@ -2248,8 +2275,9 @@ static void SCREEN_OT_area_join(wmOperatorType *ot)
ot->invoke= area_join_invoke;
ot->modal= area_join_modal;
ot->poll= screen_active_editable;
+ ot->cancel= area_join_cancel;
- ot->flag= OPTYPE_BLOCKING;
+ ot->flag= OPTYPE_BLOCKING|OPTYPE_INTERNAL;
/* rna */
RNA_def_int(ot->srna, "min_x", -100, INT_MIN, INT_MAX, "X 1", "", INT_MIN, INT_MAX);
@@ -2433,13 +2461,7 @@ static void SCREEN_OT_repeat_history(wmOperatorType *ot)
static int redo_last_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSED(event))
{
- wmWindowManager *wm= CTX_wm_manager(C);
- wmOperator *lastop;
-
- /* only for operators that are registered and did an undo push */
- for(lastop= wm->operators.last; lastop; lastop= lastop->prev)
- if((lastop->type->flag & OPTYPE_REGISTER) && (lastop->type->flag & OPTYPE_UNDO))
- break;
+ wmOperator *lastop= WM_operator_last_redo(C);
if(lastop)
WM_operator_redo_popup(C, lastop);
@@ -3044,6 +3066,7 @@ static void SCREEN_OT_border_select(wmOperatorType *ot)
ot->exec= border_select_do;
ot->invoke= WM_border_select_invoke;
ot->modal= WM_border_select_modal;
+ ot->cancel= WM_border_select_cancel;
ot->poll= ED_operator_areaactive;
@@ -3314,6 +3337,7 @@ void ED_operatortypes_screen(void)
WM_operatortype_append(ED_OT_undo);
WM_operatortype_append(ED_OT_undo_push);
WM_operatortype_append(ED_OT_redo);
+ WM_operatortype_append(ED_OT_undo_history);
}
@@ -3422,9 +3446,11 @@ void ED_keymap_screen(wmKeyConfig *keyconf)
#ifdef __APPLE__
WM_keymap_add_item(keymap, "ED_OT_undo", ZKEY, KM_PRESS, KM_OSKEY, 0);
WM_keymap_add_item(keymap, "ED_OT_redo", ZKEY, KM_PRESS, KM_SHIFT|KM_OSKEY, 0);
+ WM_keymap_add_item(keymap, "ED_OT_undo_history", ZKEY, KM_PRESS, KM_ALT|KM_OSKEY, 0);
#endif
WM_keymap_add_item(keymap, "ED_OT_undo", ZKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "ED_OT_redo", ZKEY, KM_PRESS, KM_SHIFT|KM_CTRL, 0);
+ WM_keymap_add_item(keymap, "ED_OT_undo_history", ZKEY, KM_PRESS, KM_ALT|KM_CTRL, 0);
/* render */
diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c
index db0d2314ad0..cae5c14aa97 100644
--- a/source/blender/editors/sculpt_paint/paint_image.c
+++ b/source/blender/editors/sculpt_paint/paint_image.c
@@ -3692,14 +3692,26 @@ static void do_projectpaint_draw(ProjPaintState *ps, ProjPixel *projPixel, float
}
}
-static void do_projectpaint_draw_f(ProjPaintState *ps, ProjPixel *projPixel, float *rgba, float alpha, float mask) {
+static void do_projectpaint_draw_f(ProjPaintState *ps, ProjPixel *projPixel, float *rgba, float alpha, float mask, int use_color_correction) {
if (ps->is_texbrush) {
- rgba[0] *= ps->brush->rgb[0];
- rgba[1] *= ps->brush->rgb[1];
- rgba[2] *= ps->brush->rgb[2];
+ /* rgba already holds a texture result here from higher level function */
+ float rgba_br[3];
+ if(use_color_correction){
+ srgb_to_linearrgb_v3_v3(rgba_br, ps->brush->rgb);
+ mul_v3_v3(rgba, rgba_br);
+ }
+ else{
+ mul_v3_v3(rgba, ps->brush->rgb);
+ }
}
else {
- VECCOPY(rgba, ps->brush->rgb);
+ if(use_color_correction){
+ srgb_to_linearrgb_v3_v3(rgba, ps->brush->rgb);
+ }
+ else {
+ VECCOPY(rgba, ps->brush->rgb);
+ }
+ rgba[3] = 1.0;
}
if (ps->is_airbrush==0 && mask < 1.0f) {
@@ -3736,6 +3748,7 @@ static void *do_projectpaint_thread(void *ph_v)
float falloff;
int bucket_index;
int is_floatbuf = 0;
+ int use_color_correction = 0;
const short tool = ps->tool;
rctf bucket_bounds;
@@ -3841,6 +3854,7 @@ static void *do_projectpaint_thread(void *ph_v)
last_projIma->touch = 1;
is_floatbuf = last_projIma->ibuf->rect_float ? 1 : 0;
+ use_color_correction = (last_projIma->ibuf->profile == IB_PROFILE_LINEAR_RGB) ? 1 : 0;
}
last_partial_redraw_cell = last_projIma->partRedrawRect + projPixel->bb_cell_index;
@@ -3871,7 +3885,7 @@ static void *do_projectpaint_thread(void *ph_v)
else do_projectpaint_smear(ps, projPixel, alpha, mask, smearArena, &smearPixels, co);
break;
default:
- if (is_floatbuf) do_projectpaint_draw_f(ps, projPixel, rgba, alpha, mask);
+ if (is_floatbuf) do_projectpaint_draw_f(ps, projPixel, rgba, alpha, mask, use_color_correction);
else do_projectpaint_draw(ps, projPixel, rgba, alpha, mask);
break;
}
@@ -3987,7 +4001,7 @@ static int project_paint_sub_stroke(ProjPaintState *ps, BrushPainter *painter, c
// we may want to use this later
// brush_painter_require_imbuf(painter, ((ibuf->rect_float)? 1: 0), 0, 0);
- if (brush_painter_paint(painter, project_paint_op, pos, time, pressure, ps)) {
+ if (brush_painter_paint(painter, project_paint_op, pos, time, pressure, ps, 0)) {
return 1;
}
else return 0;
@@ -4058,7 +4072,6 @@ static void imapaint_dirty_region(Image *ima, ImBuf *ibuf, int x, int y, int w,
static void imapaint_image_update(SpaceImage *sima, Image *image, ImBuf *ibuf, short texpaint)
{
if(ibuf->rect_float)
- /* TODO - should just update a portion from imapaintpartial! */
ibuf->userflags |= IB_RECT_INVALID; /* force recreate of char rect */
if(ibuf->mipmap[0])
@@ -4255,8 +4268,8 @@ static ImBuf *imapaint_lift_clone(ImBuf *ibuf, ImBuf *ibufb, int *pos)
static void imapaint_convert_brushco(ImBuf *ibufb, float *pos, int *ipos)
{
- ipos[0]= (int)(pos[0] - ibufb->x/2);
- ipos[1]= (int)(pos[1] - ibufb->y/2);
+ ipos[0]= (int)floorf((pos[0] - ibufb->x/2) + 1.0f);
+ ipos[1]= (int)floorf((pos[1] - ibufb->y/2) + 1.0f);
}
/* dosnt run for projection painting
@@ -4409,7 +4422,7 @@ static int imapaint_paint_sub_stroke(ImagePaintState *s, BrushPainter *painter,
brush_painter_require_imbuf(painter, ((ibuf->rect_float)? 1: 0), 0, 0);
- if (brush_painter_paint(painter, imapaint_paint_op, pos, time, pressure, s)) {
+ if (brush_painter_paint(painter, imapaint_paint_op, pos, time, pressure, s, ibuf->profile == IB_PROFILE_LINEAR_RGB)) {
if (update)
imapaint_image_update(s->sima, image, ibuf, texpaint);
return 1;
@@ -4863,12 +4876,7 @@ static void paint_apply_event(bContext *C, wmOperator *op, wmEvent *event)
PointerRNA itemptr;
float pressure, mousef[2];
double time;
- int tablet, mouse[2];
-
- // XXX +1 matches brush location better but
- // still not exact, find out why and fix ..
- mouse[0]= event->mval[0] + 1;
- mouse[1]= event->mval[1] + 1;
+ int tablet;
time= PIL_check_seconds_timer();
@@ -4888,8 +4896,8 @@ static void paint_apply_event(bContext *C, wmOperator *op, wmEvent *event)
pressure= pop->prev_pressure ? pop->prev_pressure : 1.0f;
if(pop->first) {
- pop->prevmouse[0]= mouse[0];
- pop->prevmouse[1]= mouse[1];
+ pop->prevmouse[0]= event->mval[0];
+ pop->prevmouse[1]= event->mval[1];
pop->starttime= time;
/* special exception here for too high pressure values on first touch in
@@ -4908,8 +4916,8 @@ static void paint_apply_event(bContext *C, wmOperator *op, wmEvent *event)
/* fill in stroke */
RNA_collection_add(op->ptr, "stroke", &itemptr);
- mousef[0] = (float)(mouse[0]);
- mousef[1] = (float)(mouse[1]);
+ mousef[0] = (float)(event->mval[0]);
+ mousef[1] = (float)(event->mval[1]);
RNA_float_set_array(&itemptr, "mouse", mousef);
RNA_float_set(&itemptr, "time", (float)(time - pop->starttime));
RNA_float_set(&itemptr, "pressure", pressure);
@@ -5012,31 +5020,45 @@ static int get_imapaint_zoom(bContext *C, float *zoomx, float *zoomy)
static void brush_drawcursor(bContext *C, int x, int y, void *UNUSED(customdata))
{
+#define PX_SIZE_FADE_MAX 12.0f
+#define PX_SIZE_FADE_MIN 4.0f
+
Brush *brush= image_paint_brush(C);
Paint *paint= paint_get_active(CTX_data_scene(C));
- if(paint && brush) {
+ if(paint && brush && paint->flags & PAINT_SHOW_BRUSH) {
float zoomx, zoomy;
+ const float size= (float)brush_size(brush);
+ const short use_zoom= get_imapaint_zoom(C, &zoomx, &zoomy);
+ const float pixel_size= MAX2(size * zoomx, size * zoomy);
+ float alpha= 0.5f;
- if(!(paint->flags & PAINT_SHOW_BRUSH))
+ /* fade out the brush (cheap trick to work around brush interfearing with sampling [#])*/
+ if(pixel_size < PX_SIZE_FADE_MIN) {
return;
+ }
+ else if (pixel_size < PX_SIZE_FADE_MAX) {
+ alpha *= (pixel_size - PX_SIZE_FADE_MIN) / (PX_SIZE_FADE_MAX - PX_SIZE_FADE_MIN);
+ }
glPushMatrix();
glTranslatef((float)x, (float)y, 0.0f);
- if(get_imapaint_zoom(C, &zoomx, &zoomy))
+ if(use_zoom)
glScalef(zoomx, zoomy, 1.0f);
- glColor4f(brush->add_col[0], brush->add_col[1], brush->add_col[2], 0.5f);
+ glColor4f(brush->add_col[0], brush->add_col[1], brush->add_col[2], alpha);
glEnable( GL_LINE_SMOOTH );
glEnable(GL_BLEND);
- glutil_draw_lined_arc(0, (float)(M_PI*2.0), (float)brush_size(brush), 40);
+ glutil_draw_lined_arc(0, (float)(M_PI*2.0), size, 40);
glDisable(GL_BLEND);
glDisable( GL_LINE_SMOOTH );
glPopMatrix();
}
+#undef PX_SIZE_FADE_MAX
+#undef PX_SIZE_FADE_MIN
}
static void toggle_paint_cursor(bContext *C, int enable)
diff --git a/source/blender/editors/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h
index bb877e4b1ee..5a0ee19d6c9 100644
--- a/source/blender/editors/sculpt_paint/paint_intern.h
+++ b/source/blender/editors/sculpt_paint/paint_intern.h
@@ -65,6 +65,7 @@ int paint_space_stroke_enabled(struct Brush *br);
int paint_stroke_modal(struct bContext *C, struct wmOperator *op, struct wmEvent *event);
int paint_stroke_exec(struct bContext *C, struct wmOperator *op);
+int paint_stroke_cancel(struct bContext *C, struct wmOperator *op);
struct ViewContext *paint_stroke_view_context(struct PaintStroke *stroke);
void *paint_stroke_mode_data(struct PaintStroke *stroke);
void paint_stroke_set_mode_data(struct PaintStroke *stroke, void *mode_data);
diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c
index 58c3446673c..7ddf5dff000 100644
--- a/source/blender/editors/sculpt_paint/paint_stroke.c
+++ b/source/blender/editors/sculpt_paint/paint_stroke.c
@@ -916,6 +916,19 @@ int paint_stroke_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
+int paint_stroke_cancel(bContext *C, wmOperator *op)
+{
+ PaintStroke *stroke = op->customdata;
+
+ if(stroke->done)
+ stroke->done(C, stroke);
+
+ MEM_freeN(stroke);
+ op->customdata = NULL;
+
+ return OPERATOR_CANCELLED;
+}
+
ViewContext *paint_stroke_view_context(PaintStroke *stroke)
{
return &stroke->vc;
diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c
index c35b742eb9e..3da19ba7346 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex.c
@@ -1600,6 +1600,13 @@ static int wpaint_invoke(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
+static int wpaint_cancel(bContext *C, wmOperator *op)
+{
+ paint_stroke_cancel(C, op);
+
+ return OPERATOR_CANCELLED;
+}
+
void PAINT_OT_weight_paint(wmOperatorType *ot)
{
@@ -1612,6 +1619,7 @@ void PAINT_OT_weight_paint(wmOperatorType *ot)
ot->modal= paint_stroke_modal;
/* ot->exec= vpaint_exec; <-- needs stroke property */
ot->poll= weight_paint_poll;
+ ot->cancel= wpaint_cancel;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
@@ -1892,6 +1900,13 @@ static int vpaint_invoke(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
+static int vpaint_cancel(bContext *C, wmOperator *op)
+{
+ paint_stroke_cancel(C, op);
+
+ return OPERATOR_CANCELLED;
+}
+
void PAINT_OT_vertex_paint(wmOperatorType *ot)
{
/* identifiers */
@@ -1903,6 +1918,7 @@ void PAINT_OT_vertex_paint(wmOperatorType *ot)
ot->modal= paint_stroke_modal;
/* ot->exec= vpaint_exec; <-- needs stroke property */
ot->poll= vertex_paint_poll;
+ ot->cancel= vpaint_cancel;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 20e74702067..be985342ea8 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -3559,6 +3559,24 @@ static int sculpt_brush_stroke_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
+static int sculpt_brush_stroke_cancel(bContext *C, wmOperator *op)
+{
+ Object *ob= CTX_data_active_object(C);
+ SculptSession *ss = ob->sculpt;
+ Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
+
+ paint_stroke_cancel(C, op);
+
+ if(ss->cache) {
+ sculpt_cache_free(ss->cache);
+ ss->cache = NULL;
+ }
+
+ sculpt_brush_exit_tex(sd);
+
+ return OPERATOR_CANCELLED;
+}
+
static void SCULPT_OT_brush_stroke(wmOperatorType *ot)
{
static EnumPropertyItem stroke_mode_items[] = {
@@ -3577,6 +3595,7 @@ static void SCULPT_OT_brush_stroke(wmOperatorType *ot)
ot->modal= paint_stroke_modal;
ot->exec= sculpt_brush_stroke_exec;
ot->poll= sculpt_poll;
+ ot->cancel= sculpt_brush_stroke_cancel;
/* flags (sculpt does own undo? (ton) */
ot->flag= OPTYPE_BLOCKING;
diff --git a/source/blender/editors/space_action/action_select.c b/source/blender/editors/space_action/action_select.c
index be8547afa23..4d0043913ab 100644
--- a/source/blender/editors/space_action/action_select.c
+++ b/source/blender/editors/space_action/action_select.c
@@ -332,6 +332,7 @@ void ACTION_OT_select_border(wmOperatorType *ot)
ot->invoke= WM_border_select_invoke;
ot->exec= actkeys_borderselect_exec;
ot->modal= WM_border_select_modal;
+ ot->cancel= WM_border_select_cancel;
ot->poll= ED_operator_action_active;
diff --git a/source/blender/editors/space_action/space_action.c b/source/blender/editors/space_action/space_action.c
index 10a1fe62cca..7a824e6bf9d 100644
--- a/source/blender/editors/space_action/space_action.c
+++ b/source/blender/editors/space_action/space_action.c
@@ -58,6 +58,7 @@
#include "UI_view2d.h"
#include "ED_space_api.h"
+#include "ED_screen.h"
#include "ED_anim_api.h"
#include "ED_markers.h"
diff --git a/source/blender/editors/space_api/spacetypes.c b/source/blender/editors/space_api/spacetypes.c
index 8d8cdcc7183..4f8cb8a57b2 100644
--- a/source/blender/editors/space_api/spacetypes.c
+++ b/source/blender/editors/space_api/spacetypes.c
@@ -70,6 +70,9 @@ void ED_spacetypes_init(void)
const ListBase *spacetypes;
SpaceType *type;
+ /* UI_UNIT_X is now a variable, is used in some spacetype inits? */
+ U.widget_unit= 20;
+
/* create space types */
ED_spacetype_outliner();
ED_spacetype_time();
diff --git a/source/blender/editors/space_buttons/buttons_header.c b/source/blender/editors/space_buttons/buttons_header.c
index 8d48836704e..19c600be937 100644
--- a/source/blender/editors/space_buttons/buttons_header.c
+++ b/source/blender/editors/space_buttons/buttons_header.c
@@ -104,7 +104,7 @@ void buttons_header_buttons(const bContext *C, ARegion *ar)
{
SpaceButs *sbuts= CTX_wm_space_buts(C);
uiBlock *block;
- int xco, yco= 1;
+ int xco, yco= 2;
buttons_context_compute(C, sbuts);
@@ -115,7 +115,7 @@ void buttons_header_buttons(const bContext *C, ARegion *ar)
uiBlockSetEmboss(block, UI_EMBOSS);
- xco -= XIC;
+ xco -= UI_UNIT_X;
// Default panels
uiBlockBeginAlign(block);
@@ -150,7 +150,7 @@ void buttons_header_buttons(const bContext *C, ARegion *ar)
uiBlockEndAlign(block);
/* always as last */
- UI_view2d_totRect_set(&ar->v2d, xco+(XIC/2), ar->v2d.tot.ymax-ar->v2d.tot.ymin);
+ UI_view2d_totRect_set(&ar->v2d, xco+(UI_UNIT_X/2), ar->v2d.tot.ymax-ar->v2d.tot.ymin);
uiEndBlock(C, block);
uiDrawBlock(C, block);
diff --git a/source/blender/editors/space_console/console_draw.c b/source/blender/editors/space_console/console_draw.c
index bf5df87610c..905fed4f30b 100644
--- a/source/blender/editors/space_console/console_draw.c
+++ b/source/blender/editors/space_console/console_draw.c
@@ -83,11 +83,13 @@ typedef struct ConsoleDrawContext {
int console_width;
int winx;
int ymin, ymax;
+#if 0 /* used by textview, may use later */
int *xy; // [2]
int *sel; // [2]
int *pos_pick; // bottom of view == 0, top of file == combine chars, end of line is lower then start.
int *mval; // [2]
int draw;
+#endif
} ConsoleDrawContext;
void console_scrollback_prompt_begin(struct SpaceConsole *sc, ConsoleLine *cl_dummy)
diff --git a/source/blender/editors/space_file/CMakeLists.txt b/source/blender/editors/space_file/CMakeLists.txt
index e161e2d4b9b..afa746ea359 100644
--- a/source/blender/editors/space_file/CMakeLists.txt
+++ b/source/blender/editors/space_file/CMakeLists.txt
@@ -51,6 +51,10 @@ set(SRC
fsmenu.h
)
+if(WITH_HEADLESS)
+ add_definitions(-DWITH_HEADLESS)
+endif()
+
if(WITH_IMAGE_OPENEXR)
add_definitions(-DWITH_OPENEXR)
endif()
diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c
index 903af649caa..a6fee359197 100644
--- a/source/blender/editors/space_file/file_draw.c
+++ b/source/blender/editors/space_file/file_draw.c
@@ -74,12 +74,6 @@
#include "file_intern.h" // own include
-/* ui geometry */
-#define IMASEL_BUTTONS_HEIGHT 40
-#define IMASEL_BUTTONS_MARGIN 6
-#define TILE_BORDER_X 8
-#define TILE_BORDER_Y 8
-
/* button events */
enum {
B_FS_DIRNAME,
@@ -523,8 +517,8 @@ void file_draw_list(const bContext *C, ARegion *ar)
file_draw_preview(block, file, sx, sy, imb, layout, !is_icon && (file->flags & IMAGEFILE));
} else {
- file_draw_icon(block, file->path, sx, sy-3, get_file_icon(file), ICON_DEFAULT_WIDTH, ICON_DEFAULT_WIDTH);
- sx += ICON_DEFAULT_WIDTH + 4;
+ file_draw_icon(block, file->path, sx, sy-(UI_UNIT_Y / 6), get_file_icon(file), ICON_DEFAULT_WIDTH_SCALE, ICON_DEFAULT_WIDTH_SCALE);
+ sx += ICON_DEFAULT_WIDTH_SCALE + 4;
}
UI_ThemeColor4(TH_TEXT);
diff --git a/source/blender/editors/space_file/file_intern.h b/source/blender/editors/space_file/file_intern.h
index f171c4936fc..1965c661685 100644
--- a/source/blender/editors/space_file/file_intern.h
+++ b/source/blender/editors/space_file/file_intern.h
@@ -43,8 +43,12 @@ struct SpaceFile;
struct ARegion *file_buttons_region(struct ScrArea *sa);
/* file_draw.c */
-#define TILE_BORDER_X 8
-#define TILE_BORDER_Y 8
+#define TILE_BORDER_X (UI_UNIT_X/4)
+#define TILE_BORDER_Y (UI_UNIT_Y/4)
+
+/* ui geometry */
+#define IMASEL_BUTTONS_HEIGHT (UI_UNIT_Y*2)
+#define IMASEL_BUTTONS_MARGIN (UI_UNIT_Y/6)
void file_draw_buttons(const bContext *C, ARegion *ar);
void file_calc_previews(const bContext *C, ARegion *ar);
diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c
index 9662b4b401f..a5d516a1417 100644
--- a/source/blender/editors/space_file/file_ops.c
+++ b/source/blender/editors/space_file/file_ops.c
@@ -301,6 +301,7 @@ void FILE_OT_select_border(wmOperatorType *ot)
ot->exec= file_border_select_exec;
ot->modal= file_border_select_modal;
ot->poll= ED_operator_file_active;
+ ot->cancel= WM_border_select_cancel;
/* rna */
WM_operator_properties_gesture_border(ot, 0);
diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c
index 9b65589ef4c..32b725e0b1f 100644
--- a/source/blender/editors/space_file/filelist.c
+++ b/source/blender/editors/space_file/filelist.c
@@ -373,7 +373,11 @@ void filelist_init_icons(void)
short x, y, k;
ImBuf *bbuf;
ImBuf *ibuf;
+#ifdef WITH_HEADLESS
+ bbuf = NULL;
+#else
bbuf = IMB_ibImageFromMemory((unsigned char*)datatoc_prvicons, datatoc_prvicons_size, IB_rect);
+#endif
if (bbuf) {
for (y=0; y<SPECIAL_IMG_ROWS; y++) {
for (x=0; x<SPECIAL_IMG_COLS; x++) {
diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c
index 968953abf62..45193a38ef5 100644
--- a/source/blender/editors/space_file/filesel.c
+++ b/source/blender/editors/space_file/filesel.c
@@ -406,7 +406,7 @@ float file_font_pointsize(void)
#else
uiStyle *style= U.uistyles.first;
uiStyleFontSet(&style->widget);
- return style->widget.points;
+ return style->widget.points * UI_DPI_FAC;
#endif
}
@@ -497,11 +497,11 @@ void ED_fileselect_init_layout(struct SpaceFile *sfile, struct ARegion *ar)
column_widths(sfile->files, layout);
if (params->display == FILE_SHORTDISPLAY) {
- maxlen = ICON_DEFAULT_WIDTH + 4 +
+ maxlen = ICON_DEFAULT_WIDTH_SCALE + 4 +
(int)layout->column_widths[COLUMN_NAME] + 12 +
(int)layout->column_widths[COLUMN_SIZE] + 12;
} else {
- maxlen = ICON_DEFAULT_WIDTH + 4 +
+ maxlen = ICON_DEFAULT_WIDTH_SCALE + 4 +
(int)layout->column_widths[COLUMN_NAME] + 12 +
#ifndef WIN32
(int)layout->column_widths[COLUMN_MODE1] + 12 +
diff --git a/source/blender/editors/space_graph/graph_select.c b/source/blender/editors/space_graph/graph_select.c
index 76883027df1..cb799b85d3a 100644
--- a/source/blender/editors/space_graph/graph_select.c
+++ b/source/blender/editors/space_graph/graph_select.c
@@ -344,6 +344,7 @@ void GRAPH_OT_select_border(wmOperatorType *ot)
ot->invoke= WM_border_select_invoke;
ot->exec= graphkeys_borderselect_exec;
ot->modal= WM_border_select_modal;
+ ot->cancel= WM_border_select_cancel;
ot->poll= graphop_visible_keyframes_poll;
diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c
index 7e881e7e62f..0210b0dd78d 100644
--- a/source/blender/editors/space_image/image_buttons.c
+++ b/source/blender/editors/space_image/image_buttons.c
@@ -556,20 +556,20 @@ static void uiblock_layer_pass_buttons(uiLayout *layout, RenderResult *rr, Image
/* menu buts */
if(render_slot) {
strp= slot_menu();
- but= uiDefButS(block, MENU, 0, strp, 0, 0, wmenu1, 20, render_slot, 0,0,0,0, "Select Slot");
+ but= uiDefButS(block, MENU, 0, strp, 0, 0, wmenu1, UI_UNIT_Y, render_slot, 0,0,0,0, "Select Slot");
uiButSetFunc(but, image_multi_cb, rr, iuser);
MEM_freeN(strp);
}
if(rr) {
strp= layer_menu(rr, &iuser->layer);
- but= uiDefButS(block, MENU, 0, strp, 0, 0, wmenu2, 20, &iuser->layer, 0,0,0,0, "Select Layer");
+ but= uiDefButS(block, MENU, 0, strp, 0, 0, wmenu2, UI_UNIT_Y, &iuser->layer, 0,0,0,0, "Select Layer");
uiButSetFunc(but, image_multi_cb, rr, iuser);
MEM_freeN(strp);
rl= BLI_findlink(&rr->layers, iuser->layer - (rr->rectf?1:0)); /* fake compo layer, return NULL is meant to be */
strp= pass_menu(rl, &iuser->pass);
- but= uiDefButS(block, MENU, 0, strp, 0, 0, wmenu3, 20, &iuser->pass, 0,0,0,0, "Select Pass");
+ but= uiDefButS(block, MENU, 0, strp, 0, 0, wmenu3, UI_UNIT_Y, &iuser->pass, 0,0,0,0, "Select Pass");
uiButSetFunc(but, image_multi_cb, rr, iuser);
MEM_freeN(strp);
}
@@ -662,7 +662,6 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char
block= uiLayoutGetBlock(layout);
-
imaptr= RNA_property_pointer_get(ptr, prop);
ima= imaptr.data;
iuser= userptr->data;
@@ -719,21 +718,17 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char
}
}
else {
- row= uiLayoutRow(layout, 0);
- uiItemR(row, &imaptr, "source", 0, NULL, ICON_NONE);
+ uiItemR(layout, &imaptr, "source", 0, NULL, ICON_NONE);
if(ima->source != IMA_SRC_GENERATED) {
row= uiLayoutRow(layout, 1);
- split = uiLayoutSplit(row, 0.0, 0);
if (ima->packedfile)
- uiItemO(split, "", ICON_PACKAGE, "image.unpack");
+ uiItemO(row, "", ICON_PACKAGE, "image.unpack");
else
- uiItemO(split, "", ICON_UGLYPACKAGE, "image.pack");
+ uiItemO(row, "", ICON_UGLYPACKAGE, "image.pack");
- split = uiLayoutSplit(row, 0.0, 0);
- row= uiLayoutRow(split, 1);
+ row= uiLayoutRow(row, 0);
uiLayoutSetEnabled(row, ima->packedfile==NULL);
-
uiItemR(row, &imaptr, "filepath", 0, "", ICON_NONE);
uiItemO(row, "", ICON_FILE_REFRESH, "image.reload");
}
@@ -771,11 +766,10 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char
col= uiLayoutColumn(split, 0);
uiItemR(col, &imaptr, "use_fields", 0, NULL, ICON_NONE);
row= uiLayoutRow(col, 0);
- uiItemR(row, &imaptr, "field_order", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
uiLayoutSetActive(row, RNA_boolean_get(&imaptr, "use_fields"));
-
- col= uiLayoutColumn(split, 0);
- uiItemR(col, &imaptr, "use_premultiply", 0, NULL, ICON_NONE);
+ uiItemR(row, &imaptr, "field_order", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
+
+ uiItemR(split, &imaptr, "use_premultiply", 0, NULL, ICON_NONE);
}
}
@@ -787,10 +781,9 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char
col= uiLayoutColumn(split, 0);
sprintf(str, "(%d) Frames", iuser->framenr);
- row= uiLayoutRow(col, 1);
uiItemR(col, userptr, "frame_duration", 0, str, ICON_NONE);
if(ima->anim) {
- block= uiLayoutGetBlock(row);
+ block= uiLayoutGetBlock(col);
but= uiDefBut(block, BUT, 0, "Match Movie Length", 0, 0, UI_UNIT_X*2, UI_UNIT_Y, NULL, 0, 0, 0, 0, "Set the number of frames to match the movie or sequence.");
uiButSetFunc(but, set_frames_cb, ima, iuser);
}
@@ -810,8 +803,7 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char
uiItemR(col, &imaptr, "generated_width", 0, "X", ICON_NONE);
uiItemR(col, &imaptr, "generated_height", 0, "Y", ICON_NONE);
- col= uiLayoutColumn(split, 0);
- uiItemR(col, &imaptr, "generated_type", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
+ uiItemR(split, &imaptr, "generated_type", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
}
}
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index f48daa39c59..10b8cb238aa 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -1925,6 +1925,7 @@ void IMAGE_OT_sample_line(wmOperatorType *ot)
ot->modal= WM_gesture_straightline_modal;
ot->exec= sample_line_exec;
ot->poll= space_image_main_area_poll;
+ ot->cancel= WM_gesture_straightline_cancel;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
diff --git a/source/blender/editors/space_info/info_report.c b/source/blender/editors/space_info/info_report.c
index 937b683e880..c8bda434227 100644
--- a/source/blender/editors/space_info/info_report.c
+++ b/source/blender/editors/space_info/info_report.c
@@ -302,6 +302,7 @@ void INFO_OT_select_border(wmOperatorType *ot)
ot->invoke= WM_border_select_invoke;
ot->exec= borderselect_exec;
ot->modal= WM_border_select_modal;
+ ot->cancel= WM_border_select_cancel;
ot->poll= ED_operator_info_active;
diff --git a/source/blender/editors/space_logic/logic_buttons.c b/source/blender/editors/space_logic/logic_buttons.c
index e894fd9cff5..16e916928a9 100644
--- a/source/blender/editors/space_logic/logic_buttons.c
+++ b/source/blender/editors/space_logic/logic_buttons.c
@@ -206,6 +206,7 @@ void LOGIC_OT_links_cut(wmOperatorType *ot)
ot->invoke= WM_gesture_lines_invoke;
ot->modal= WM_gesture_lines_modal;
ot->exec= cut_links_exec;
+ ot->cancel= WM_gesture_lines_cancel;
ot->poll= ED_operator_logic_active;
diff --git a/source/blender/editors/space_logic/logic_window.c b/source/blender/editors/space_logic/logic_window.c
index 0cbc67a3504..a45e7d39c76 100644
--- a/source/blender/editors/space_logic/logic_window.c
+++ b/source/blender/editors/space_logic/logic_window.c
@@ -3785,6 +3785,8 @@ static void draw_actuator_camera(uiLayout *layout, PointerRNA *ptr)
row = uiLayoutRow(layout, 1);
uiItemR(row, ptr, "min", 0, NULL, ICON_NONE);
uiItemR(row, ptr, "max", 0, NULL, ICON_NONE);
+
+ uiItemR(layout, ptr, "damping", 0, NULL, ICON_NONE);
}
static void draw_actuator_constraint(uiLayout *layout, PointerRNA *ptr, bContext *C)
diff --git a/source/blender/editors/space_nla/nla_select.c b/source/blender/editors/space_nla/nla_select.c
index 0f0a4c0ad4c..8ef63b9a83d 100644
--- a/source/blender/editors/space_nla/nla_select.c
+++ b/source/blender/editors/space_nla/nla_select.c
@@ -333,6 +333,7 @@ void NLA_OT_select_border(wmOperatorType *ot)
ot->invoke= WM_border_select_invoke;
ot->exec= nlaedit_borderselect_exec;
ot->modal= WM_border_select_modal;
+ ot->cancel= WM_border_select_cancel;
ot->poll= nlaop_poll_tweakmode_off;
diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c
index d967e2240e6..e539334c282 100644
--- a/source/blender/editors/space_node/node_edit.c
+++ b/source/blender/editors/space_node/node_edit.c
@@ -1086,6 +1086,13 @@ static int snode_bg_viewmove_invoke(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
+static int snode_bg_viewmove_cancel(bContext *UNUSED(C), wmOperator *op)
+{
+ MEM_freeN(op->customdata);
+ op->customdata= NULL;
+
+ return OPERATOR_CANCELLED;
+}
void NODE_OT_backimage_move(wmOperatorType *ot)
{
@@ -1098,6 +1105,7 @@ void NODE_OT_backimage_move(wmOperatorType *ot)
ot->invoke= snode_bg_viewmove_invoke;
ot->modal= snode_bg_viewmove_modal;
ot->poll= composite_node_active;
+ ot->cancel= snode_bg_viewmove_cancel;
/* flags */
ot->flag= OPTYPE_BLOCKING;
@@ -1358,10 +1366,17 @@ static int node_resize_invoke(bContext *C, wmOperator *op, wmEvent *event)
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1],
&snode->mx, &snode->my);
- /* rect we're interested in is just the bottom right corner */
totr= node->totr;
- totr.xmin= totr.xmax-10.0f;
- totr.ymax= totr.ymin+10.0f;
+
+ if(node->flag & NODE_HIDDEN) {
+ /* right part of node */
+ totr.xmin= node->totr.xmax-20.0f;
+ }
+ else {
+ /* bottom right corner */
+ totr.xmin= totr.xmax-10.0f;
+ totr.ymax= totr.ymin+10.0f;
+ }
if(BLI_in_rctf(&totr, snode->mx, snode->my)) {
NodeSizeWidget *nsw= MEM_callocN(sizeof(NodeSizeWidget), "size widget op data");
@@ -1384,6 +1399,14 @@ static int node_resize_invoke(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_CANCELLED|OPERATOR_PASS_THROUGH;
}
+static int node_resize_cancel(bContext *UNUSED(C), wmOperator *op)
+{
+ MEM_freeN(op->customdata);
+ op->customdata= NULL;
+
+ return OPERATOR_CANCELLED;
+}
+
void NODE_OT_resize(wmOperatorType *ot)
{
/* identifiers */
@@ -1394,6 +1417,7 @@ void NODE_OT_resize(wmOperatorType *ot)
ot->invoke= node_resize_invoke;
ot->modal= node_resize_modal;
ot->poll= ED_operator_node_active;
+ ot->cancel= node_resize_cancel;
/* flags */
ot->flag= OPTYPE_BLOCKING;
@@ -2279,6 +2303,18 @@ static int node_link_invoke(bContext *C, wmOperator *op, wmEvent *event)
}
}
+static int node_link_cancel(bContext *C, wmOperator *op)
+{
+ SpaceNode *snode= CTX_wm_space_node(C);
+ bNodeLinkDrag *nldrag= op->customdata;
+
+ nodeRemLink(snode->edittree, nldrag->link);
+ BLI_remlink(&snode->linkdrag, nldrag);
+ MEM_freeN(nldrag);
+
+ return OPERATOR_CANCELLED;
+}
+
void NODE_OT_link(wmOperatorType *ot)
{
/* identifiers */
@@ -2290,6 +2326,7 @@ void NODE_OT_link(wmOperatorType *ot)
ot->modal= node_link_modal;
// ot->exec= node_link_exec;
ot->poll= ED_operator_node_active;
+ ot->cancel= node_link_cancel;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
@@ -2402,6 +2439,7 @@ void NODE_OT_links_cut(wmOperatorType *ot)
ot->invoke= WM_gesture_lines_invoke;
ot->modal= WM_gesture_lines_modal;
ot->exec= cut_links_exec;
+ ot->cancel= WM_gesture_lines_cancel;
ot->poll= ED_operator_node_active;
diff --git a/source/blender/editors/space_node/node_select.c b/source/blender/editors/space_node/node_select.c
index a1ef75f3976..1abcaccc939 100644
--- a/source/blender/editors/space_node/node_select.c
+++ b/source/blender/editors/space_node/node_select.c
@@ -215,6 +215,7 @@ void NODE_OT_select_border(wmOperatorType *ot)
ot->invoke= node_border_select_invoke;
ot->exec= node_borderselect_exec;
ot->modal= WM_border_select_modal;
+ ot->cancel= WM_border_select_cancel;
ot->poll= ED_operator_node_active;
diff --git a/source/blender/editors/space_outliner/outliner.c b/source/blender/editors/space_outliner/outliner.c
index 037b1db56d6..bd2d591a8c8 100644
--- a/source/blender/editors/space_outliner/outliner.c
+++ b/source/blender/editors/space_outliner/outliner.c
@@ -57,6 +57,7 @@
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
+#include "BLI_math_base.h"
#if defined WIN32 && !defined _LIBC
# include "BLI_fnmatch.h" /* use fnmatch included in blenlib */
@@ -106,21 +107,17 @@
#include "outliner_intern.h"
-
-#define OL_H 19
-#define OL_X 18
-
#define OL_Y_OFFSET 2
-#define OL_TOG_RESTRICT_VIEWX 54
-#define OL_TOG_RESTRICT_SELECTX 36
-#define OL_TOG_RESTRICT_RENDERX 18
+#define OL_TOG_RESTRICT_VIEWX (UI_UNIT_X*3)
+#define OL_TOG_RESTRICT_SELECTX (UI_UNIT_X*2)
+#define OL_TOG_RESTRICT_RENDERX UI_UNIT_X
#define OL_TOGW OL_TOG_RESTRICT_VIEWX
-#define OL_RNA_COLX 300
-#define OL_RNA_COL_SIZEX 150
-#define OL_RNA_COL_SPACEX 50
+#define OL_RNA_COLX (UI_UNIT_X*15)
+#define OL_RNA_COL_SIZEX (UI_UNIT_X*7.5)
+#define OL_RNA_COL_SPACEX (UI_UNIT_X*2.5)
#define TS_CHUNK 128
@@ -260,7 +257,7 @@ static void outliner_height(SpaceOops *soops, ListBase *lb, int *h)
TreeStoreElem *tselem= TREESTORE(te);
if((tselem->flag & TSE_CLOSED)==0)
outliner_height(soops, &te->subtree, h);
- (*h) += OL_H;
+ (*h) += UI_UNIT_Y;
te= te->next;
}
}
@@ -297,7 +294,7 @@ static void outliner_rna_width(SpaceOops *soops, ListBase *lb, int *w, int start
*w = startx+100;
if((tselem->flag & TSE_CLOSED)==0)
- outliner_rna_width(soops, &te->subtree, w, startx+OL_X);
+ outliner_rna_width(soops, &te->subtree, w, startx+UI_UNIT_X);
te= te->next;
}
}
@@ -440,7 +437,7 @@ static void outliner_sort(SpaceOops *soops, ListBase *lb)
static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *idv,
TreeElement *parent, short type, short index);
-#define LOG2I(x) (int)(log(x)/log(2.0))
+#define LOG2I(x) (int)(log(x)/M_LN2)
static void outliner_add_passes(SpaceOops *soops, TreeElement *tenla, ID *id, SceneRenderLayer *srl)
{
@@ -2485,13 +2482,13 @@ static int tree_element_type_active(bContext *C, Scene *scene, SpaceOops *soops,
static int do_outliner_item_activate(bContext *C, Scene *scene, ARegion *ar, SpaceOops *soops, TreeElement *te, int extend, const float mval[2])
{
- if(mval[1]>te->ys && mval[1]<te->ys+OL_H) {
+ if(mval[1]>te->ys && mval[1]<te->ys+UI_UNIT_Y) {
TreeStoreElem *tselem= TREESTORE(te);
int openclose= 0;
/* open close icon */
if((te->flag & TE_ICONROW)==0) { // hidden icon, no open/close
- if( mval[0]>te->xs && mval[0]<te->xs+OL_X)
+ if( mval[0]>te->xs && mval[0]<te->xs+UI_UNIT_X)
openclose= 1;
}
@@ -2510,7 +2507,7 @@ static int do_outliner_item_activate(bContext *C, Scene *scene, ARegion *ar, Spa
return 1;
}
/* name and first icon */
- else if(mval[0]>te->xs+OL_X && mval[0]<te->xend) {
+ else if(mval[0]>te->xs+UI_UNIT_X && mval[0]<te->xend) {
/* always makes active object */
if(tselem->type!=TSE_SEQUENCE && tselem->type!=TSE_SEQ_STRIP && tselem->type!=TSE_SEQUENCE_DUP)
@@ -2597,7 +2594,7 @@ static int outliner_item_activate(bContext *C, wmOperator *op, wmEvent *event)
int row;
/* get row number - 100 here is just a dummy value since we don't need the column */
- UI_view2d_listview_view_to_cell(&ar->v2d, 1000, OL_H, 0.0f, OL_Y_OFFSET,
+ UI_view2d_listview_view_to_cell(&ar->v2d, 1000, UI_UNIT_Y, 0.0f, OL_Y_OFFSET,
fmval[0], fmval[1], NULL, &row);
/* select relevant row */
@@ -2631,7 +2628,7 @@ void OUTLINER_OT_item_activate(wmOperatorType *ot)
static int do_outliner_item_openclose(bContext *C, SpaceOops *soops, TreeElement *te, int all, const float mval[2])
{
- if(mval[1]>te->ys && mval[1]<te->ys+OL_H) {
+ if(mval[1]>te->ys && mval[1]<te->ys+UI_UNIT_Y) {
TreeStoreElem *tselem= TREESTORE(te);
/* all below close/open? */
@@ -2696,11 +2693,11 @@ void OUTLINER_OT_item_openclose(wmOperatorType *ot)
static int do_outliner_item_rename(bContext *C, ARegion *ar, SpaceOops *soops, TreeElement *te, const float mval[2])
{
- if(mval[1]>te->ys && mval[1]<te->ys+OL_H) {
+ if(mval[1]>te->ys && mval[1]<te->ys+UI_UNIT_Y) {
TreeStoreElem *tselem= TREESTORE(te);
/* name and first icon */
- if(mval[0]>te->xs+OL_X && mval[0]<te->xend) {
+ if(mval[0]>te->xs+UI_UNIT_X && mval[0]<te->xend) {
/* can't rename rna datablocks entries */
if(ELEM3(tselem->type, TSE_RNA_STRUCT, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM))
@@ -2861,12 +2858,12 @@ static void outliner_set_coordinates_element(SpaceOops *soops, TreeElement *te,
/* store coord and continue, we need coordinates for elements outside view too */
te->xs= (float)startx;
te->ys= (float)(*starty);
- *starty-= OL_H;
+ *starty-= UI_UNIT_Y;
if((tselem->flag & TSE_CLOSED)==0) {
TreeElement *ten;
for(ten= te->subtree.first; ten; ten= ten->next) {
- outliner_set_coordinates_element(soops, ten, startx+OL_X, starty);
+ outliner_set_coordinates_element(soops, ten, startx+UI_UNIT_X, starty);
}
}
@@ -2876,7 +2873,7 @@ static void outliner_set_coordinates_element(SpaceOops *soops, TreeElement *te,
static void outliner_set_coordinates(ARegion *ar, SpaceOops *soops)
{
TreeElement *te;
- int starty= (int)(ar->v2d.tot.ymax)-OL_H;
+ int starty= (int)(ar->v2d.tot.ymax)-UI_UNIT_Y;
int startx= 0;
for(te= soops->tree.first; te; te= te->next) {
@@ -3731,7 +3728,7 @@ void OUTLINER_OT_data_operation(wmOperatorType *ot)
static int do_outliner_operation_event(bContext *C, Scene *scene, ARegion *ar, SpaceOops *soops, TreeElement *te, wmEvent *event, const float mval[2])
{
- if(mval[1]>te->ys && mval[1]<te->ys+OL_H) {
+ if(mval[1]>te->ys && mval[1]<te->ys+UI_UNIT_Y) {
int scenelevel=0, objectlevel=0, idlevel=0, datalevel=0;
TreeStoreElem *tselem= TREESTORE(te);
@@ -4309,7 +4306,10 @@ static void tselem_draw_icon_uibut(struct DrawIconArg *arg, int icon)
if(arg->x >= arg->xmax)
UI_icon_draw(arg->x, arg->y, icon);
else {
- uiBut *but= uiDefIconBut(arg->block, LABEL, 0, icon, arg->x-4, arg->y, ICON_DEFAULT_WIDTH, ICON_DEFAULT_WIDTH, NULL, 0.0, 0.0, 1.0, arg->alpha, (arg->id && arg->id->lib) ? arg->id->lib->name : "");
+ /* XXX investigate: button placement of icons is way different than UI_icon_draw? */
+ float ufac= UI_UNIT_X/20.0f;
+ uiBut *but= uiDefIconBut(arg->block, LABEL, 0, icon, arg->x-3.0f*ufac, arg->y, UI_UNIT_X-4.0f*ufac, UI_UNIT_Y-4.0f*ufac, NULL, 0.0, 0.0, 1.0, arg->alpha, (arg->id && arg->id->lib) ? arg->id->lib->name : "");
+
if(arg->id)
uiButSetDragID(but, arg->id);
}
@@ -4572,7 +4572,7 @@ static void outliner_draw_iconrow(bContext *C, uiBlock *block, Scene *scene, Spa
for(te= lb->first; te; te= te->next) {
/* exit drawing early */
- if((*offsx) - OL_X > xmax)
+ if((*offsx) - UI_UNIT_X > xmax)
break;
tselem= TREESTORE(te);
@@ -4589,19 +4589,21 @@ static void outliner_draw_iconrow(bContext *C, uiBlock *block, Scene *scene, Spa
else active= tree_element_type_active(NULL, scene, soops, te, tselem, 0);
if(active) {
+ float ufac= UI_UNIT_X/20.0f;
+
uiSetRoundBox(15);
glColor4ub(255, 255, 255, 100);
- uiRoundBox( (float)*offsx-0.5f, (float)ys-1.0f, (float)*offsx+OL_H-3.0f, (float)ys+OL_H-3.0f, OL_H/2.0f-2.0f);
+ uiRoundBox( (float)*offsx-0.5f*ufac, (float)ys-1.0f*ufac, (float)*offsx+UI_UNIT_Y-3.0f*ufac, (float)ys+UI_UNIT_Y-3.0f*ufac, UI_UNIT_Y/2.0f-2.0f*ufac);
glEnable(GL_BLEND); /* roundbox disables */
}
tselem_draw_icon(block, xmax, (float)*offsx, (float)ys, tselem, te, 0.5f);
te->xs= (float)*offsx;
te->ys= (float)ys;
- te->xend= (short)*offsx+OL_X;
+ te->xend= (short)*offsx+UI_UNIT_X;
te->flag |= TE_ICONROW; // for click
- (*offsx) += OL_X;
+ (*offsx) += UI_UNIT_X;
}
/* this tree element always has same amount of branches, so dont draw */
@@ -4621,7 +4623,7 @@ static void outliner_set_coord_tree_element(SpaceOops *soops, TreeElement *te, i
te->ys= (float)(*starty);
for(ten= te->subtree.first; ten; ten= ten->next) {
- outliner_set_coord_tree_element(soops, ten, startx+OL_X, starty);
+ outliner_set_coord_tree_element(soops, ten, startx+UI_UNIT_X, starty);
}
}
@@ -4630,16 +4632,17 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene
{
TreeElement *ten;
TreeStoreElem *tselem;
+ float ufac= UI_UNIT_X/20.0f;
int offsx= 0, active=0; // active=1 active obj, else active data
tselem= TREESTORE(te);
- if(*starty+2*OL_H >= ar->v2d.cur.ymin && *starty<= ar->v2d.cur.ymax) {
+ if(*starty+2*UI_UNIT_Y >= ar->v2d.cur.ymin && *starty<= ar->v2d.cur.ymax) {
int xmax= ar->v2d.cur.xmax;
/* icons can be ui buts, we dont want it to overlap with restrict */
if((soops->flag & SO_HIDE_RESTRICTCOLS)==0)
- xmax-= OL_TOGW+ICON_DEFAULT_WIDTH;
+ xmax-= OL_TOGW+UI_UNIT_X;
glEnable(GL_BLEND);
@@ -4708,7 +4711,7 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene
/* active circle */
if(active) {
uiSetRoundBox(15);
- uiRoundBox( (float)startx+OL_H-1.5f, (float)*starty+2.0f, (float)startx+2.0f*OL_H-4.0f, (float)*starty+OL_H-1.0f, OL_H/2.0f-2.0f);
+ uiRoundBox( (float)startx+UI_UNIT_Y-1.5f*ufac, (float)*starty+2.0f*ufac, (float)startx+2.0f*UI_UNIT_Y-4.0f*ufac, (float)*starty+UI_UNIT_Y-1.0f*ufac, UI_UNIT_Y/2.0f-2.0f*ufac);
glEnable(GL_BLEND); /* roundbox disables it */
te->flag |= TE_ACTIVE; // for lookup in display hierarchies
@@ -4720,35 +4723,35 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene
if(tselem->type==0 && ELEM(te->idcode, ID_OB, ID_SCE))
icon_x = startx;
else
- icon_x = startx+5;
+ icon_x = startx+5*ufac;
// icons a bit higher
if(tselem->flag & TSE_CLOSED)
- UI_icon_draw((float)icon_x, (float)*starty+2, ICON_DISCLOSURE_TRI_RIGHT);
+ UI_icon_draw((float)icon_x, (float)*starty+2*ufac, ICON_DISCLOSURE_TRI_RIGHT);
else
- UI_icon_draw((float)icon_x, (float)*starty+2, ICON_DISCLOSURE_TRI_DOWN);
+ UI_icon_draw((float)icon_x, (float)*starty+2*ufac, ICON_DISCLOSURE_TRI_DOWN);
}
- offsx+= OL_X;
+ offsx+= UI_UNIT_X;
/* datatype icon */
if(!(ELEM(tselem->type, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM))) {
// icons a bit higher
- tselem_draw_icon(block, xmax, (float)startx+offsx, (float)*starty+2, tselem, te, 1.0f);
+ tselem_draw_icon(block, xmax, (float)startx+offsx, (float)*starty+2*ufac, tselem, te, 1.0f);
- offsx+= OL_X;
+ offsx+= UI_UNIT_X;
}
else
- offsx+= 2;
+ offsx+= 2*ufac;
if(tselem->type==0 && tselem->id->lib) {
glPixelTransferf(GL_ALPHA_SCALE, 0.5f);
if(tselem->id->flag & LIB_INDIRECT)
- UI_icon_draw((float)startx+offsx, (float)*starty+2, ICON_LIBRARY_DATA_INDIRECT);
+ UI_icon_draw((float)startx+offsx, (float)*starty+2*ufac, ICON_LIBRARY_DATA_INDIRECT);
else
- UI_icon_draw((float)startx+offsx, (float)*starty+2, ICON_LIBRARY_DATA_DIRECT);
+ UI_icon_draw((float)startx+offsx, (float)*starty+2*ufac, ICON_LIBRARY_DATA_DIRECT);
glPixelTransferf(GL_ALPHA_SCALE, 1.0f);
- offsx+= OL_X;
+ offsx+= UI_UNIT_X;
}
glDisable(GL_BLEND);
@@ -4757,9 +4760,9 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene
else if(ELEM(tselem->type, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM)) UI_ThemeColorBlend(TH_BACK, TH_TEXT, 0.75f);
else UI_ThemeColor(TH_TEXT);
- UI_DrawString(startx+offsx, *starty+5, te->name);
+ UI_DrawString(startx+offsx, *starty+5*ufac, te->name);
- offsx+= (int)(OL_X + UI_GetStringWidth(te->name));
+ offsx+= (int)(UI_UNIT_X + UI_GetStringWidth(te->name));
/* closed item, we draw the icons, not when it's a scene, or master-server list though */
if(tselem->flag & TSE_CLOSED) {
@@ -4770,7 +4773,7 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene
// divider
UI_ThemeColorShade(TH_BACK, -40);
- glRecti(tempx -10, *starty+4, tempx -8, *starty+OL_H-4);
+ glRecti(tempx -10, *starty+4, tempx -8, *starty+UI_UNIT_Y-4);
glEnable(GL_BLEND);
glPixelTransferf(GL_ALPHA_SCALE, 0.5);
@@ -4789,16 +4792,16 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene
te->xend= startx+offsx;
if((tselem->flag & TSE_CLOSED)==0) {
- *starty-= OL_H;
+ *starty-= UI_UNIT_Y;
for(ten= te->subtree.first; ten; ten= ten->next)
- outliner_draw_tree_element(C, block, scene, ar, soops, ten, startx+OL_X, starty);
+ outliner_draw_tree_element(C, block, scene, ar, soops, ten, startx+UI_UNIT_X, starty);
}
else {
for(ten= te->subtree.first; ten; ten= ten->next)
outliner_set_coord_tree_element(soops, te, startx, starty);
- *starty-= OL_H;
+ *starty-= UI_UNIT_Y;
}
}
@@ -4817,12 +4820,12 @@ static void outliner_draw_hierarchy(SpaceOops *soops, ListBase *lb, int startx,
/* horizontal line? */
if(tselem->type==0 && (te->idcode==ID_OB || te->idcode==ID_SCE))
- glRecti(startx, *starty, startx+OL_X, *starty-1);
+ glRecti(startx, *starty, startx+UI_UNIT_X, *starty-1);
- *starty-= OL_H;
+ *starty-= UI_UNIT_Y;
if((tselem->flag & TSE_CLOSED)==0)
- outliner_draw_hierarchy(soops, &te->subtree, startx+OL_X, starty);
+ outliner_draw_hierarchy(soops, &te->subtree, startx+UI_UNIT_X, starty);
}
/* vertical line */
@@ -4831,7 +4834,7 @@ static void outliner_draw_hierarchy(SpaceOops *soops, ListBase *lb, int startx,
tselem= TREESTORE(te);
if(tselem->type==0 && te->idcode==ID_OB) {
- glRecti(startx, y1+OL_H, startx+1, y2);
+ glRecti(startx, y1+UI_UNIT_Y, startx+1, y2);
}
}
}
@@ -4847,13 +4850,13 @@ static void outliner_draw_struct_marks(ARegion *ar, SpaceOops *soops, ListBase *
/* selection status */
if((tselem->flag & TSE_CLOSED)==0)
if(tselem->type == TSE_RNA_STRUCT)
- glRecti(0, *starty+1, (int)ar->v2d.cur.xmax+V2D_SCROLL_WIDTH, *starty+OL_H-1);
+ glRecti(0, *starty+1, (int)ar->v2d.cur.xmax+V2D_SCROLL_WIDTH, *starty+UI_UNIT_Y-1);
- *starty-= OL_H;
+ *starty-= UI_UNIT_Y;
if((tselem->flag & TSE_CLOSED)==0) {
outliner_draw_struct_marks(ar, soops, &te->subtree, starty);
if(tselem->type == TSE_RNA_STRUCT)
- fdrawline(0, (float)*starty+OL_H, ar->v2d.cur.xmax+V2D_SCROLL_WIDTH, (float)*starty+OL_H);
+ fdrawline(0, (float)*starty+UI_UNIT_Y, ar->v2d.cur.xmax+V2D_SCROLL_WIDTH, (float)*starty+UI_UNIT_Y);
}
}
}
@@ -4868,9 +4871,9 @@ static void outliner_draw_selection(ARegion *ar, SpaceOops *soops, ListBase *lb,
/* selection status */
if(tselem->flag & TSE_SELECTED) {
- glRecti(0, *starty+1, (int)ar->v2d.cur.xmax, *starty+OL_H-1);
+ glRecti(0, *starty+1, (int)ar->v2d.cur.xmax, *starty+UI_UNIT_Y-1);
}
- *starty-= OL_H;
+ *starty-= UI_UNIT_Y;
if((tselem->flag & TSE_CLOSED)==0) outliner_draw_selection(ar, soops, &te->subtree, starty);
}
}
@@ -4888,24 +4891,24 @@ static void outliner_draw_tree(bContext *C, uiBlock *block, Scene *scene, ARegio
/* struct marks */
UI_ThemeColorShadeAlpha(TH_BACK, -15, -200);
//UI_ThemeColorShade(TH_BACK, -20);
- starty= (int)ar->v2d.tot.ymax-OL_H-OL_Y_OFFSET;
+ starty= (int)ar->v2d.tot.ymax-UI_UNIT_Y-OL_Y_OFFSET;
outliner_draw_struct_marks(ar, soops, &soops->tree, &starty);
}
/* always draw selection fill before hierarchy */
UI_GetThemeColor3fv(TH_BACK, col);
glColor3f(col[0]+0.06f, col[1]+0.08f, col[2]+0.10f);
- starty= (int)ar->v2d.tot.ymax-OL_H-OL_Y_OFFSET;
+ starty= (int)ar->v2d.tot.ymax-UI_UNIT_Y-OL_Y_OFFSET;
outliner_draw_selection(ar, soops, &soops->tree, &starty);
// grey hierarchy lines
UI_ThemeColorBlend(TH_BACK, TH_TEXT, 0.2f);
- starty= (int)ar->v2d.tot.ymax-OL_H/2-OL_Y_OFFSET;
+ starty= (int)ar->v2d.tot.ymax-UI_UNIT_Y/2-OL_Y_OFFSET;
startx= 6;
outliner_draw_hierarchy(soops, &soops->tree, startx, &starty);
// items themselves
- starty= (int)ar->v2d.tot.ymax-OL_H-OL_Y_OFFSET;
+ starty= (int)ar->v2d.tot.ymax-UI_UNIT_Y-OL_Y_OFFSET;
startx= 0;
for(te= soops->tree.first; te; te= te->next) {
outliner_draw_tree_element(C, block, scene, ar, soops, te, startx, &starty);
@@ -4919,11 +4922,11 @@ static void outliner_back(ARegion *ar)
UI_ThemeColorShade(TH_BACK, 6);
ystart= (int)ar->v2d.tot.ymax;
- ystart= OL_H*(ystart/(OL_H))-OL_Y_OFFSET;
+ ystart= UI_UNIT_Y*(ystart/(UI_UNIT_Y))-OL_Y_OFFSET;
- while(ystart+2*OL_H > ar->v2d.cur.ymin) {
- glRecti(0, ystart, (int)ar->v2d.cur.xmax+V2D_SCROLL_WIDTH, ystart+OL_H);
- ystart-= 2*OL_H;
+ while(ystart+2*UI_UNIT_Y > ar->v2d.cur.ymin) {
+ glRecti(0, ystart, (int)ar->v2d.cur.xmax+V2D_SCROLL_WIDTH, ystart+UI_UNIT_Y);
+ ystart-= 2*UI_UNIT_Y;
}
}
@@ -4937,11 +4940,11 @@ static void outliner_draw_restrictcols(ARegion *ar)
UI_ThemeColorShade(TH_BACK, 6);
ystart= (int)ar->v2d.tot.ymax;
- ystart= OL_H*(ystart/(OL_H))-OL_Y_OFFSET;
+ ystart= UI_UNIT_Y*(ystart/(UI_UNIT_Y))-OL_Y_OFFSET;
- while(ystart+2*OL_H > ar->v2d.cur.ymin) {
- glRecti((int)ar->v2d.cur.xmax-OL_TOGW, ystart, (int)ar->v2d.cur.xmax, ystart+OL_H);
- ystart-= 2*OL_H;
+ while(ystart+2*UI_UNIT_Y > ar->v2d.cur.ymin) {
+ glRecti((int)ar->v2d.cur.xmax-OL_TOGW, ystart, (int)ar->v2d.cur.xmax, ystart+UI_UNIT_Y);
+ ystart-= 2*UI_UNIT_Y;
}
UI_ThemeColorShadeAlpha(TH_BACK, -15, -200);
@@ -5225,7 +5228,7 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
for(te= lb->first; te; te= te->next) {
tselem= TREESTORE(te);
- if(te->ys+2*OL_H >= ar->v2d.cur.ymin && te->ys <= ar->v2d.cur.ymax) {
+ if(te->ys+2*UI_UNIT_Y >= ar->v2d.cur.ymin && te->ys <= ar->v2d.cur.ymax) {
/* objects have toggle-able restriction flags */
if(tselem->type==0 && te->idcode==ID_OB) {
PointerRNA ptr;
@@ -5235,17 +5238,17 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
uiBlockSetEmboss(block, UI_EMBOSSN);
bt= uiDefIconButR(block, ICONTOG, 0, ICON_RESTRICT_VIEW_OFF,
- (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (int)te->ys, 17, OL_H-1,
+ (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1,
&ptr, "hide", -1, 0, 0, -1, -1, NULL);
uiButSetFunc(bt, restrictbutton_view_cb, scene, ob);
bt= uiDefIconButR(block, ICONTOG, 0, ICON_RESTRICT_SELECT_OFF,
- (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_SELECTX, (int)te->ys, 17, OL_H-1,
+ (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_SELECTX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1,
&ptr, "hide_select", -1, 0, 0, -1, -1, NULL);
uiButSetFunc(bt, restrictbutton_sel_cb, scene, ob);
bt= uiDefIconButR(block, ICONTOG, 0, ICON_RESTRICT_RENDER_OFF,
- (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_RENDERX, (int)te->ys, 17, OL_H-1,
+ (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_RENDERX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1,
&ptr, "hide_render", -1, 0, 0, -1, -1, NULL);
uiButSetFunc(bt, restrictbutton_rend_cb, scene, ob);
@@ -5259,15 +5262,15 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
uiBlockSetEmboss(block, UI_EMBOSSN);
restrict_bool= group_restrict_flag(gr, OB_RESTRICT_VIEW);
- bt = uiDefIconBut(block, BUT, 0, restrict_bool ? ICON_RESTRICT_VIEW_ON : ICON_RESTRICT_VIEW_OFF, (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (int)te->ys, 17, OL_H-1, NULL, 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View");
+ bt = uiDefIconBut(block, BUT, 0, restrict_bool ? ICON_RESTRICT_VIEW_ON : ICON_RESTRICT_VIEW_OFF, (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, NULL, 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View");
uiButSetFunc(bt, restrictbutton_gr_restrict_view, scene, gr);
restrict_bool= group_restrict_flag(gr, OB_RESTRICT_SELECT);
- bt = uiDefIconBut(block, BUT, 0, restrict_bool ? ICON_RESTRICT_SELECT_ON : ICON_RESTRICT_SELECT_OFF, (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_SELECTX, (int)te->ys, 17, OL_H-1, NULL, 0, 0, 0, 0, "Restrict/Allow selection in the 3D View");
+ bt = uiDefIconBut(block, BUT, 0, restrict_bool ? ICON_RESTRICT_SELECT_ON : ICON_RESTRICT_SELECT_OFF, (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_SELECTX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, NULL, 0, 0, 0, 0, "Restrict/Allow selection in the 3D View");
uiButSetFunc(bt, restrictbutton_gr_restrict_select, scene, gr);
restrict_bool= group_restrict_flag(gr, OB_RESTRICT_RENDER);
- bt = uiDefIconBut(block, BUT, 0, restrict_bool ? ICON_RESTRICT_RENDER_ON : ICON_RESTRICT_RENDER_OFF, (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_RENDERX, (int)te->ys, 17, OL_H-1, NULL, 0, 0, 0, 0, "Restrict/Allow renderability");
+ bt = uiDefIconBut(block, BUT, 0, restrict_bool ? ICON_RESTRICT_RENDER_ON : ICON_RESTRICT_RENDER_OFF, (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_RENDERX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, NULL, 0, 0, 0, 0, "Restrict/Allow renderability");
uiButSetFunc(bt, restrictbutton_gr_restrict_render, scene, gr);
uiBlockSetEmboss(block, UI_EMBOSS);
@@ -5277,7 +5280,7 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
uiBlockSetEmboss(block, UI_EMBOSSN);
bt= uiDefIconButBitI(block, ICONTOGN, SCE_LAY_DISABLE, 0, ICON_CHECKBOX_HLT-1,
- (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (int)te->ys, 17, OL_H-1, te->directdata, 0, 0, 0, 0, "Render this RenderLayer");
+ (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, te->directdata, 0, 0, 0, 0, "Render this RenderLayer");
uiButSetFunc(bt, restrictbutton_r_lay_cb, tselem->id, NULL);
uiBlockSetEmboss(block, UI_EMBOSS);
@@ -5290,13 +5293,13 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
bt= uiDefIconButBitI(block, ICONTOG, passflag, 0, ICON_CHECKBOX_HLT-1,
- (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (int)te->ys, 17, OL_H-1, layflag, 0, 0, 0, 0, "Render this Pass");
+ (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, layflag, 0, 0, 0, 0, "Render this Pass");
uiButSetFunc(bt, restrictbutton_r_lay_cb, tselem->id, NULL);
layflag++; /* is lay_xor */
if(ELEM8(passflag, SCE_PASS_SPEC, SCE_PASS_SHADOW, SCE_PASS_AO, SCE_PASS_REFLECT, SCE_PASS_REFRACT, SCE_PASS_INDIRECT, SCE_PASS_EMIT, SCE_PASS_ENVIRONMENT))
bt= uiDefIconButBitI(block, TOG, passflag, 0, (*layflag & passflag)?ICON_DOT:ICON_BLANK1,
- (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_SELECTX, (int)te->ys, 17, OL_H-1, layflag, 0, 0, 0, 0, "Exclude this Pass from Combined");
+ (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_SELECTX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, layflag, 0, 0, 0, 0, "Exclude this Pass from Combined");
uiButSetFunc(bt, restrictbutton_r_lay_cb, tselem->id, NULL);
uiBlockSetEmboss(block, UI_EMBOSS);
@@ -5307,11 +5310,11 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
uiBlockSetEmboss(block, UI_EMBOSSN);
bt= uiDefIconButBitI(block, ICONTOGN, eModifierMode_Realtime, 0, ICON_RESTRICT_VIEW_OFF,
- (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (int)te->ys, 17, OL_H-1, &(md->mode), 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View");
+ (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, &(md->mode), 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View");
uiButSetFunc(bt, restrictbutton_modifier_cb, scene, ob);
bt= uiDefIconButBitI(block, ICONTOGN, eModifierMode_Render, 0, ICON_RESTRICT_RENDER_OFF,
- (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_RENDERX, (int)te->ys, 17, OL_H-1, &(md->mode), 0, 0, 0, 0, "Restrict/Allow renderability");
+ (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_RENDERX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, &(md->mode), 0, 0, 0, 0, "Restrict/Allow renderability");
uiButSetFunc(bt, restrictbutton_modifier_cb, scene, ob);
}
else if(tselem->type==TSE_POSE_CHANNEL) {
@@ -5320,11 +5323,11 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
uiBlockSetEmboss(block, UI_EMBOSSN);
bt= uiDefIconButBitI(block, ICONTOG, BONE_HIDDEN_P, 0, ICON_RESTRICT_VIEW_OFF,
- (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (int)te->ys, 17, OL_H-1, &(bone->flag), 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View");
+ (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, &(bone->flag), 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View");
uiButSetFunc(bt, restrictbutton_bone_cb, NULL, bone);
bt= uiDefIconButBitI(block, ICONTOG, BONE_UNSELECTABLE, 0, ICON_RESTRICT_SELECT_OFF,
- (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_SELECTX, (int)te->ys, 17, OL_H-1, &(bone->flag), 0, 0, 0, 0, "Restrict/Allow selection in the 3D View");
+ (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_SELECTX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, &(bone->flag), 0, 0, 0, 0, "Restrict/Allow selection in the 3D View");
uiButSetFunc(bt, restrictbutton_bone_cb, NULL, NULL);
}
else if(tselem->type==TSE_EBONE) {
@@ -5332,11 +5335,11 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
uiBlockSetEmboss(block, UI_EMBOSSN);
bt= uiDefIconButBitI(block, ICONTOG, BONE_HIDDEN_A, 0, ICON_RESTRICT_VIEW_OFF,
- (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (int)te->ys, 17, OL_H-1, &(ebone->flag), 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View");
+ (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, &(ebone->flag), 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View");
uiButSetFunc(bt, restrictbutton_ebone_cb, NULL, ebone);
bt= uiDefIconButBitI(block, ICONTOG, BONE_UNSELECTABLE, 0, ICON_RESTRICT_SELECT_OFF,
- (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_SELECTX, (int)te->ys, 17, OL_H-1, &(ebone->flag), 0, 0, 0, 0, "Restrict/Allow selection in the 3D View");
+ (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_SELECTX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, &(ebone->flag), 0, 0, 0, 0, "Restrict/Allow selection in the 3D View");
uiButSetFunc(bt, restrictbutton_ebone_cb, NULL, NULL);
}
}
@@ -5377,19 +5380,19 @@ static void outliner_draw_rnabuts(uiBlock *block, Scene *scene, ARegion *ar, Spa
for(te= lb->first; te; te= te->next) {
tselem= TREESTORE(te);
- if(te->ys+2*OL_H >= ar->v2d.cur.ymin && te->ys <= ar->v2d.cur.ymax) {
+ if(te->ys+2*UI_UNIT_Y >= ar->v2d.cur.ymin && te->ys <= ar->v2d.cur.ymax) {
if(tselem->type == TSE_RNA_PROPERTY) {
ptr= &te->rnaptr;
prop= te->directdata;
if(!(RNA_property_type(prop) == PROP_POINTER && (tselem->flag & TSE_CLOSED)==0))
- uiDefAutoButR(block, ptr, prop, -1, "", ICON_NONE, sizex, (int)te->ys, OL_RNA_COL_SIZEX, OL_H-1);
+ uiDefAutoButR(block, ptr, prop, -1, "", ICON_NONE, sizex, (int)te->ys, OL_RNA_COL_SIZEX, UI_UNIT_Y-1);
}
else if(tselem->type == TSE_RNA_ARRAY_ELEM) {
ptr= &te->rnaptr;
prop= te->directdata;
- uiDefAutoButR(block, ptr, prop, te->index, "", ICON_NONE, sizex, (int)te->ys, OL_RNA_COL_SIZEX, OL_H-1);
+ uiDefAutoButR(block, ptr, prop, te->index, "", ICON_NONE, sizex, (int)te->ys, OL_RNA_COL_SIZEX, UI_UNIT_Y-1);
}
}
@@ -5444,7 +5447,7 @@ static uiBlock *operator_search_menu(bContext *C, ARegion *ar, void *arg_kmi)
/* fake button, it holds space for search items */
uiDefBut(block, LABEL, 0, "", 10, 15, 150, uiSearchBoxhHeight(), NULL, 0, 0, 0, 0, NULL);
- but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, 256, 10, 0, 150, 19, 0, 0, "");
+ but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, 256, 10, 0, 150, UI_UNIT_Y, 0, 0, "");
uiButSetSearchFunc(but, operator_search_cb, arg_kmi, operator_call_cb, ot);
uiBoundsBlock(block, 6);
@@ -5583,11 +5586,11 @@ static void outliner_draw_keymapbuts(uiBlock *block, ARegion *ar, SpaceOops *soo
for(te= lb->first; te; te= te->next) {
tselem= TREESTORE(te);
- if(te->ys+2*OL_H >= ar->v2d.cur.ymin && te->ys <= ar->v2d.cur.ymax) {
+ if(te->ys+2*UI_UNIT_Y >= ar->v2d.cur.ymin && te->ys <= ar->v2d.cur.ymax) {
uiBut *but;
const char *str;
int xstart= 240;
- int butw1= 20; /* operator */
+ int butw1= UI_UNIT_X; /* operator */
int butw2= 90; /* event type, menus */
int butw3= 43; /* modifiers */
@@ -5597,7 +5600,7 @@ static void outliner_draw_keymapbuts(uiBlock *block, ARegion *ar, SpaceOops *soo
/* modal map? */
if(kmi->propvalue);
else {
- uiDefBlockBut(block, operator_search_menu, kmi, "", xstart, (int)te->ys+1, butw1, OL_H-1, "Assign new Operator");
+ uiDefBlockBut(block, operator_search_menu, kmi, "", xstart, (int)te->ys+1, butw1, UI_UNIT_Y-1, "Assign new Operator");
}
xstart+= butw1+10;
@@ -5605,43 +5608,43 @@ static void outliner_draw_keymapbuts(uiBlock *block, ARegion *ar, SpaceOops *soo
kmi->maptype= keymap_menu_type(kmi->type);
str= keymap_type_menu();
- but= uiDefButS(block, MENU, 0, str, xstart, (int)te->ys+1, butw2, OL_H-1, &kmi->maptype, 0, 0, 0, 0, "Event type");
+ but= uiDefButS(block, MENU, 0, str, xstart, (int)te->ys+1, butw2, UI_UNIT_Y-1, &kmi->maptype, 0, 0, 0, 0, "Event type");
uiButSetFunc(but, keymap_type_cb, kmi, NULL);
xstart+= butw2+5;
/* edit actual event */
switch(kmi->maptype) {
case OL_KM_KEYBOARD:
- uiDefKeyevtButS(block, 0, "", xstart, (int)te->ys+1, butw2, OL_H-1, &kmi->type, "Key code");
+ uiDefKeyevtButS(block, 0, "", xstart, (int)te->ys+1, butw2, UI_UNIT_Y-1, &kmi->type, "Key code");
xstart+= butw2+5;
break;
case OL_KM_MOUSE:
str= keymap_mouse_menu();
- uiDefButS(block, MENU, 0, str, xstart,(int)te->ys+1, butw2, OL_H-1, &kmi->type, 0, 0, 0, 0, "Mouse button");
+ uiDefButS(block, MENU, 0, str, xstart,(int)te->ys+1, butw2, UI_UNIT_Y-1, &kmi->type, 0, 0, 0, 0, "Mouse button");
xstart+= butw2+5;
break;
case OL_KM_TWEAK:
str= keymap_tweak_menu();
- uiDefButS(block, MENU, 0, str, xstart, (int)te->ys+1, butw2, OL_H-1, &kmi->type, 0, 0, 0, 0, "Tweak gesture");
+ uiDefButS(block, MENU, 0, str, xstart, (int)te->ys+1, butw2, UI_UNIT_Y-1, &kmi->type, 0, 0, 0, 0, "Tweak gesture");
xstart+= butw2+5;
str= keymap_tweak_dir_menu();
- uiDefButS(block, MENU, 0, str, xstart, (int)te->ys+1, butw2, OL_H-1, &kmi->val, 0, 0, 0, 0, "Tweak gesture direction");
+ uiDefButS(block, MENU, 0, str, xstart, (int)te->ys+1, butw2, UI_UNIT_Y-1, &kmi->val, 0, 0, 0, 0, "Tweak gesture direction");
xstart+= butw2+5;
break;
}
/* modifiers */
- uiDefButS(block, OPTION, 0, "Shift", xstart, (int)te->ys+1, butw3+5, OL_H-1, &kmi->shift, 0, 0, 0, 0, "Modifier"); xstart+= butw3+5;
- uiDefButS(block, OPTION, 0, "Ctrl", xstart, (int)te->ys+1, butw3, OL_H-1, &kmi->ctrl, 0, 0, 0, 0, "Modifier"); xstart+= butw3;
- uiDefButS(block, OPTION, 0, "Alt", xstart, (int)te->ys+1, butw3, OL_H-1, &kmi->alt, 0, 0, 0, 0, "Modifier"); xstart+= butw3;
- uiDefButS(block, OPTION, 0, "OS", xstart, (int)te->ys+1, butw3, OL_H-1, &kmi->oskey, 0, 0, 0, 0, "Modifier"); xstart+= butw3;
+ uiDefButS(block, OPTION, 0, "Shift", xstart, (int)te->ys+1, butw3+5, UI_UNIT_Y-1, &kmi->shift, 0, 0, 0, 0, "Modifier"); xstart+= butw3+5;
+ uiDefButS(block, OPTION, 0, "Ctrl", xstart, (int)te->ys+1, butw3, UI_UNIT_Y-1, &kmi->ctrl, 0, 0, 0, 0, "Modifier"); xstart+= butw3;
+ uiDefButS(block, OPTION, 0, "Alt", xstart, (int)te->ys+1, butw3, UI_UNIT_Y-1, &kmi->alt, 0, 0, 0, 0, "Modifier"); xstart+= butw3;
+ uiDefButS(block, OPTION, 0, "OS", xstart, (int)te->ys+1, butw3, UI_UNIT_Y-1, &kmi->oskey, 0, 0, 0, 0, "Modifier"); xstart+= butw3;
xstart+= 5;
- uiDefKeyevtButS(block, 0, "", xstart, (int)te->ys+1, butw3, OL_H-1, &kmi->keymodifier, "Key Modifier code");
+ uiDefKeyevtButS(block, 0, "", xstart, (int)te->ys+1, butw3, UI_UNIT_Y-1, &kmi->keymodifier, "Key Modifier code");
xstart+= butw3+5;
/* rna property */
if(kmi->ptr && kmi->ptr->data) {
- uiDefBut(block, LABEL, 0, "(RNA property)", xstart, (int)te->ys+1, butw2, OL_H-1, &kmi->oskey, 0, 0, 0, 0, ""); xstart+= butw2;
+ uiDefBut(block, LABEL, 0, "(RNA property)", xstart, (int)te->ys+1, butw2, UI_UNIT_Y-1, &kmi->oskey, 0, 0, 0, 0, ""); xstart+= butw2;
}
(void)xstart;
@@ -5662,7 +5665,7 @@ static void outliner_buttons(const bContext *C, uiBlock *block, ARegion *ar, Spa
for(te= lb->first; te; te= te->next) {
tselem= TREESTORE(te);
- if(te->ys+2*OL_H >= ar->v2d.cur.ymin && te->ys <= ar->v2d.cur.ymax) {
+ if(te->ys+2*UI_UNIT_Y >= ar->v2d.cur.ymin && te->ys <= ar->v2d.cur.ymax) {
if(tselem->flag & TSE_TEXTBUT) {
@@ -5679,10 +5682,10 @@ static void outliner_buttons(const bContext *C, uiBlock *block, ARegion *ar, Spa
dx= (int)UI_GetStringWidth(te->name);
if(dx<100) dx= 100;
- spx=te->xs+2*OL_X-4;
+ spx=te->xs+2*UI_UNIT_X-4;
if(spx+dx+10>ar->v2d.cur.xmax) dx = ar->v2d.cur.xmax-spx-10;
- bt= uiDefBut(block, TEX, OL_NAMEBUTTON, "", spx, (int)te->ys, dx+10, OL_H-1, (void *)te->name, 1.0, (float)len, 0, 0, "");
+ bt= uiDefBut(block, TEX, OL_NAMEBUTTON, "", spx, (int)te->ys, dx+10, UI_UNIT_Y-1, (void *)te->name, 1.0, (float)len, 0, 0, "");
uiButSetRenameFunc(bt, namebutton_cb, tselem);
/* returns false if button got removed */
@@ -5716,7 +5719,7 @@ void draw_outliner(const bContext *C)
* (OL_RNA_COL_X), whichever is wider...
* - column 2 is fixed at OL_RNA_COL_SIZEX
*
- * (*) XXX max width for now is a fixed factor of OL_X*(max_indention+100)
+ * (*) XXX max width for now is a fixed factor of UI_UNIT_X*(max_indention+100)
*/
/* get actual width of column 1 */
diff --git a/source/blender/editors/space_script/script_header.c b/source/blender/editors/space_script/script_header.c
index 57a1d36e3a2..d88d4296008 100644
--- a/source/blender/editors/space_script/script_header.c
+++ b/source/blender/editors/space_script/script_header.c
@@ -106,14 +106,14 @@ void script_header_buttons(const bContext *C, ARegion *ar)
xmax= GetButStringLength("View");
uiDefPulldownBut(block, dummy_viewmenu, CTX_wm_area(C),
- "View", xco, yco-2, xmax-3, 24, "");
- xco+=XIC+xmax;
+ "View", xco, yco-2, xmax-3, UI_UNIT_Y, "");
+ xco+=UI_UNIT_X+xmax;
}
uiBlockSetEmboss(block, UI_EMBOSS);
/* always as last */
- UI_view2d_totRect_set(&ar->v2d, xco+XIC+80, ar->v2d.tot.ymax-ar->v2d.tot.ymin);
+ UI_view2d_totRect_set(&ar->v2d, xco+UI_UNIT_X+80, ar->v2d.tot.ymax-ar->v2d.tot.ymin);
uiEndBlock(C, block);
uiDrawBlock(C, block);
diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c
index f351d52db07..119c5da309e 100644
--- a/source/blender/editors/space_sequencer/sequencer_draw.c
+++ b/source/blender/editors/space_sequencer/sequencer_draw.c
@@ -550,15 +550,17 @@ static void draw_shadedstrip(Sequence *seq, unsigned char col[3], float x1, floa
glShadeModel(GL_SMOOTH);
glBegin(GL_QUADS);
- if(seq->flag & SELECT) UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, -50);
+ if(seq->flag & SEQ_INVALID_EFFECT) { col[0]= 255; col[1]= 0; col[2]= 255; }
+ else if(seq->flag & SELECT) UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, -50);
else UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, 0);
glColor3ubv(col);
glVertex2f(x1,y1);
glVertex2f(x2,y1);
-
- if(seq->flag & SELECT) UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, 5);
+
+ if(seq->flag & SEQ_INVALID_EFFECT) { col[0]= 255; col[1]= 0; col[2]= 255; }
+ else if(seq->flag & SELECT) UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, 5);
else UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, -5);
glColor3ubv((GLubyte *)col);
diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c
index 71ed7928bc8..c8965c4d3db 100644
--- a/source/blender/editors/space_sequencer/sequencer_edit.c
+++ b/source/blender/editors/space_sequencer/sequencer_edit.c
@@ -124,7 +124,7 @@ typedef struct TransSeq {
int startstill, endstill;
int startdisp, enddisp;
int startofs, endofs;
- int final_left, final_right;
+ /* int final_left, final_right; */ /* UNUSED */
int len;
} TransSeq;
@@ -2817,6 +2817,7 @@ void SEQUENCER_OT_view_ghost_border(wmOperatorType *ot)
ot->exec= view_ghost_border_exec;
ot->modal= WM_border_select_modal;
ot->poll= sequencer_view_poll;
+ ot->cancel= WM_border_select_cancel;
/* flags */
ot->flag= 0;
diff --git a/source/blender/editors/space_sequencer/sequencer_select.c b/source/blender/editors/space_sequencer/sequencer_select.c
index 8b4bfb2e042..8d5f372f55e 100644
--- a/source/blender/editors/space_sequencer/sequencer_select.c
+++ b/source/blender/editors/space_sequencer/sequencer_select.c
@@ -871,6 +871,7 @@ void SEQUENCER_OT_select_border(wmOperatorType *ot)
ot->invoke= WM_border_select_invoke;
ot->exec= sequencer_borderselect_exec;
ot->modal= WM_border_select_modal;
+ ot->cancel= WM_border_select_cancel;
ot->poll= ED_operator_sequencer_active;
diff --git a/source/blender/editors/space_sound/sound_header.c b/source/blender/editors/space_sound/sound_header.c
index 60707e18187..2246eb310b5 100644
--- a/source/blender/editors/space_sound/sound_header.c
+++ b/source/blender/editors/space_sound/sound_header.c
@@ -113,14 +113,14 @@ void sound_header_buttons(const bContext *C, ARegion *ar)
xmax= GetButStringLength("View");
uiDefPulldownBut(block, dummy_viewmenu, CTX_wm_area(C),
- "View", xco, yco-2, xmax-3, 24, "");
- xco+=XIC+xmax;
+ "View", xco, yco-2, xmax-3, UI_UNIT_Y, "");
+ xco+=UI_UNIT_X+xmax;
}
uiBlockSetEmboss(block, UI_EMBOSS);
/* always as last */
- UI_view2d_totRect_set(&ar->v2d, xco+XIC+80, ar->v2d.tot.ymax-ar->v2d.tot.ymin);
+ UI_view2d_totRect_set(&ar->v2d, xco+UI_UNIT_X+80, ar->v2d.tot.ymax-ar->v2d.tot.ymin);
uiEndBlock(C, block);
uiDrawBlock(C, block);
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index 391eecbbbae..35edd961b1e 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -5812,7 +5812,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
/* multiply view with object matrix.
* local viewmat and persmat, to calculate projections */
- ED_view3d_init_mats_rv3d(ob, rv3d);
+ ED_view3d_init_mats_rv3d_gl(ob, rv3d);
/* which wire color */
if((flag & DRAW_CONSTCOLOR) == 0) {
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index fb67e38cbf7..6833dec2e43 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -208,13 +208,18 @@ void ED_view3d_init_mats_rv3d(struct Object *ob, struct RegionView3D *rv3d)
mul_m4_m4m4(rv3d->viewmatob, ob->obmat, rv3d->viewmat);
mul_m4_m4m4(rv3d->persmatob, ob->obmat, rv3d->persmat);
+ /* initializes object space clipping, speeds up clip tests */
+ ED_view3d_local_clipping(rv3d, ob->obmat);
+}
+
+void ED_view3d_init_mats_rv3d_gl(struct Object *ob, struct RegionView3D *rv3d)
+{
+ ED_view3d_init_mats_rv3d(ob, rv3d);
+
/* we have to multiply instead of loading viewmatob to make
it work with duplis using displists, otherwise it will
override the dupli-matrix */
glMultMatrixf(ob->obmat);
-
- /* initializes object space clipping, speeds up clip tests */
- ED_view3d_local_clipping(rv3d, ob->obmat);
}
/* ******************** default callbacks for view3d space ***************** */
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index 31aae28dd61..9ff73767b4c 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -904,6 +904,13 @@ static int view3d_camera_active_poll(bContext *C)
return 0;
}
+static int viewrotate_cancel(bContext *C, wmOperator *op)
+{
+ viewops_data_free(C, op);
+
+ return OPERATOR_CANCELLED;
+}
+
void VIEW3D_OT_rotate(wmOperatorType *ot)
{
@@ -916,6 +923,7 @@ void VIEW3D_OT_rotate(wmOperatorType *ot)
ot->invoke= viewrotate_invoke;
ot->modal= viewrotate_modal;
ot->poll= ED_operator_region_view3d_active;
+ ot->cancel= viewrotate_cancel;
/* flags */
ot->flag= OPTYPE_BLOCKING|OPTYPE_GRAB_POINTER;
@@ -1058,6 +1066,13 @@ static int viewmove_invoke(bContext *C, wmOperator *op, wmEvent *event)
}
}
+static int viewmove_cancel(bContext *C, wmOperator *op)
+{
+ viewops_data_free(C, op);
+
+ return OPERATOR_CANCELLED;
+}
+
void VIEW3D_OT_move(wmOperatorType *ot)
{
@@ -1070,6 +1085,7 @@ void VIEW3D_OT_move(wmOperatorType *ot)
ot->invoke= viewmove_invoke;
ot->modal= viewmove_modal;
ot->poll= ED_operator_view3d_active;
+ ot->cancel= viewmove_cancel;
/* flags */
ot->flag= OPTYPE_BLOCKING|OPTYPE_GRAB_POINTER;
@@ -1414,6 +1430,12 @@ static int viewzoom_invoke(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_FINISHED;
}
+static int viewzoom_cancel(bContext *C, wmOperator *op)
+{
+ viewops_data_free(C, op);
+
+ return OPERATOR_CANCELLED;
+}
void VIEW3D_OT_zoom(wmOperatorType *ot)
{
@@ -1427,6 +1449,7 @@ void VIEW3D_OT_zoom(wmOperatorType *ot)
ot->exec= viewzoom_exec;
ot->modal= viewzoom_modal;
ot->poll= ED_operator_region_view3d_active;
+ ot->cancel= viewzoom_cancel;
/* flags */
ot->flag= OPTYPE_BLOCKING|OPTYPE_GRAB_POINTER;
@@ -1641,6 +1664,13 @@ static int viewdolly_poll(bContext *C)
return 0;
}
+static int viewdolly_cancel(bContext *C, wmOperator *op)
+{
+ viewops_data_free(C, op);
+
+ return OPERATOR_CANCELLED;
+}
+
void VIEW3D_OT_dolly(wmOperatorType *ot)
{
/* identifiers */
@@ -1653,6 +1683,7 @@ void VIEW3D_OT_dolly(wmOperatorType *ot)
ot->exec= viewdolly_exec;
ot->modal= viewdolly_modal;
ot->poll= viewdolly_poll;
+ ot->cancel= viewdolly_cancel;
/* flags */
ot->flag= OPTYPE_BLOCKING|OPTYPE_GRAB_POINTER;
@@ -2046,6 +2077,7 @@ void VIEW3D_OT_render_border(wmOperatorType *ot)
ot->invoke= WM_border_select_invoke;
ot->exec= render_border_exec;
ot->modal= WM_border_select_modal;
+ ot->cancel= WM_border_select_cancel;
ot->poll= view3d_camera_active_poll;
@@ -2201,6 +2233,7 @@ void VIEW3D_OT_zoom_border(wmOperatorType *ot)
ot->invoke= view3d_zoom_border_invoke;
ot->exec= view3d_zoom_border_exec;
ot->modal= WM_border_select_modal;
+ ot->cancel= WM_border_select_cancel;
ot->poll= ED_operator_region_view3d_active;
@@ -2839,6 +2872,7 @@ void VIEW3D_OT_clip_border(wmOperatorType *ot)
ot->invoke= view3d_clipping_invoke;
ot->exec= view3d_clipping_exec;
ot->modal= WM_border_select_modal;
+ ot->cancel= WM_border_select_cancel;
ot->poll= ED_operator_region_view3d_active;
diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c
index fce23df3810..75c8d5cae73 100644
--- a/source/blender/editors/space_view3d/view3d_header.c
+++ b/source/blender/editors/space_view3d/view3d_header.c
@@ -445,9 +445,9 @@ void uiTemplateEditModeSelection(uiLayout *layout, struct bContext *C)
row= uiLayoutRow(layout, 1);
block= uiLayoutGetBlock(row);
- uiDefIconButBitS(block, TOG, SCE_SELECT_VERTEX, B_SEL_VERT, ICON_VERTEXSEL, 0,0,XIC,YIC, &em->selectmode, 1.0, 0.0, 0, 0, "Vertex select mode");
- uiDefIconButBitS(block, TOG, SCE_SELECT_EDGE, B_SEL_EDGE, ICON_EDGESEL, 0,0,XIC,YIC, &em->selectmode, 1.0, 0.0, 0, 0, "Edge select mode");
- uiDefIconButBitS(block, TOG, SCE_SELECT_FACE, B_SEL_FACE, ICON_FACESEL, 0,0,XIC,YIC, &em->selectmode, 1.0, 0.0, 0, 0, "Face select mode");
+ uiDefIconButBitS(block, TOG, SCE_SELECT_VERTEX, B_SEL_VERT, ICON_VERTEXSEL, 0,0,UI_UNIT_X,UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0, "Vertex select mode");
+ uiDefIconButBitS(block, TOG, SCE_SELECT_EDGE, B_SEL_EDGE, ICON_EDGESEL, 0,0,UI_UNIT_X,UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0, "Edge select mode");
+ uiDefIconButBitS(block, TOG, SCE_SELECT_FACE, B_SEL_FACE, ICON_FACESEL, 0,0,UI_UNIT_X,UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0, "Face select mode");
BKE_mesh_end_editmesh(obedit->data, em);
}
@@ -485,7 +485,7 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C)
uiBlockBeginAlign(block);
uiDefIconTextButS(block, MENU, B_MODESELECT, object_mode_icon(v3d->modeselect), view3d_modeselect_pup(scene) ,
- 0,0,126 * dpi_fac,20, &(v3d->modeselect), 0, 0, 0, 0, "Mode");
+ 0,0,126 * dpi_fac, UI_UNIT_Y, &(v3d->modeselect), 0, 0, 0, 0, "Mode");
uiBlockEndAlign(block);
/* Draw type */
@@ -508,10 +508,10 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C)
/* NDOF */
/* Not implemented yet
if (G.ndofdevice ==0 ) {
- uiDefIconTextButC(block, ICONTEXTROW,B_NDOF, ICON_NDOF_TURN, ndof_pup(), 0,0,XIC+10,YIC, &(v3d->ndofmode), 0, 3.0, 0, 0, "Ndof mode");
+ uiDefIconTextButC(block, ICONTEXTROW,B_NDOF, ICON_NDOF_TURN, ndof_pup(), 0,0,UI_UNIT_X+10,UI_UNIT_Y, &(v3d->ndofmode), 0, 3.0, 0, 0, "Ndof mode");
uiDefIconButC(block, TOG, B_NDOF, ICON_NDOF_DOM,
- 0,0,XIC,YIC,
+ 0,0,UI_UNIT_X,UI_UNIT_Y,
&v3d->ndoffilter, 0, 1, 0, 0, "dominant axis");
}
*/
@@ -522,9 +522,9 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C)
block= uiLayoutGetBlock(row);
if(v3d->twflag & V3D_USE_MANIPULATOR) {
- uiDefIconButBitC(block, TOG, V3D_MANIP_TRANSLATE, B_MAN_TRANS, ICON_MAN_TRANS, 0,0,XIC,YIC, &v3d->twtype, 1.0, 0.0, 0, 0, "Translate manipulator mode");
- uiDefIconButBitC(block, TOG, V3D_MANIP_ROTATE, B_MAN_ROT, ICON_MAN_ROT, 0,0,XIC,YIC, &v3d->twtype, 1.0, 0.0, 0, 0, "Rotate manipulator mode");
- uiDefIconButBitC(block, TOG, V3D_MANIP_SCALE, B_MAN_SCALE, ICON_MAN_SCALE, 0,0,XIC,YIC, &v3d->twtype, 1.0, 0.0, 0, 0, "Scale manipulator mode");
+ uiDefIconButBitC(block, TOG, V3D_MANIP_TRANSLATE, B_MAN_TRANS, ICON_MAN_TRANS, 0,0,UI_UNIT_X,UI_UNIT_Y, &v3d->twtype, 1.0, 0.0, 0, 0, "Translate manipulator mode");
+ uiDefIconButBitC(block, TOG, V3D_MANIP_ROTATE, B_MAN_ROT, ICON_MAN_ROT, 0,0,UI_UNIT_X,UI_UNIT_Y, &v3d->twtype, 1.0, 0.0, 0, 0, "Rotate manipulator mode");
+ uiDefIconButBitC(block, TOG, V3D_MANIP_SCALE, B_MAN_SCALE, ICON_MAN_SCALE, 0,0,UI_UNIT_X,UI_UNIT_Y, &v3d->twtype, 1.0, 0.0, 0, 0, "Scale manipulator mode");
}
if (v3d->twmode > (BIF_countTransformOrientation(C) - 1) + V3D_MANIP_CUSTOM) {
@@ -532,7 +532,7 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C)
}
str_menu = BIF_menustringTransformOrientation(C, "Orientation");
- uiDefButC(block, MENU, B_MAN_MODE, str_menu,0,0,70 * dpi_fac, YIC, &v3d->twmode, 0, 0, 0, 0, "Transform Orientation");
+ uiDefButC(block, MENU, B_MAN_MODE, str_menu,0,0,70 * dpi_fac, UI_UNIT_Y, &v3d->twmode, 0, 0, 0, 0, "Transform Orientation");
MEM_freeN((void *)str_menu);
}
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index fb3c0a63b7d..9290e1fc631 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -485,11 +485,8 @@ static void do_lasso_select_mesh(ViewContext *vc, int mcords[][2], short moves,
if (extend == 0 && select)
EM_deselect_all(vc->em);
- /* workaround: init mats first, EM_mask_init_backbuf_border can change
- view matrix to pixel space, breaking edge select with backbuf. fixes bug [#20936] */
-
- /* [#21018] breaks zbuf select. run below. only if bbsel fails */
- /* ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d) */
+ /* for non zbuf projections, dont change the GL state */
+ ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
glLoadMatrixf(vc->rv3d->viewmat);
bbsel= EM_mask_init_backbuf_border(vc, mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
@@ -497,15 +494,13 @@ static void do_lasso_select_mesh(ViewContext *vc, int mcords[][2], short moves,
if(ts->selectmode & SCE_SELECT_VERTEX) {
if (bbsel) {
EM_backbuf_checkAndSelectVerts(vc->em, select);
- } else {
- ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */
+ }
+ else {
mesh_foreachScreenVert(vc, do_lasso_select_mesh__doSelectVert, &data, 1);
}
}
if(ts->selectmode & SCE_SELECT_EDGE) {
- /* Does both bbsel and non-bbsel versions (need screen cos for both) */
- ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */
-
+ /* Does both bbsel and non-bbsel versions (need screen cos for both) */
data.pass = 0;
mesh_foreachScreenEdge(vc, do_lasso_select_mesh__doSelectEdge, &data, 0);
@@ -518,8 +513,8 @@ static void do_lasso_select_mesh(ViewContext *vc, int mcords[][2], short moves,
if(ts->selectmode & SCE_SELECT_FACE) {
if (bbsel) {
EM_backbuf_checkAndSelectFaces(vc->em, select);
- } else {
- ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */
+ }
+ else {
mesh_foreachScreenFace(vc, do_lasso_select_mesh__doSelectFace, &data);
}
}
@@ -875,6 +870,7 @@ void VIEW3D_OT_select_lasso(wmOperatorType *ot)
ot->modal= WM_gesture_lasso_modal;
ot->exec= view3d_lasso_select_exec;
ot->poll= view3d_selectable_data;
+ ot->cancel= WM_gesture_lasso_cancel;
/* flags */
ot->flag= OPTYPE_UNDO;
@@ -1490,12 +1486,8 @@ static int do_mesh_box_select(ViewContext *vc, rcti *rect, int select, int exten
if (extend == 0 && select)
EM_deselect_all(vc->em);
- /* workaround: init mats first, EM_mask_init_backbuf_border can change
- view matrix to pixel space, breaking edge select with backbuf. fixes bug #20936 */
- /*ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);*/ /* for foreach's screen/vert projection */
-
- /* [#21018] breaks zbuf select. run below. only if bbsel fails */
- /* ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d) */
+ /* for non zbuf projections, dont change the GL state */
+ ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
glLoadMatrixf(vc->rv3d->viewmat);
bbsel= EM_init_backbuf_border(vc, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
@@ -1504,7 +1496,6 @@ static int do_mesh_box_select(ViewContext *vc, rcti *rect, int select, int exten
if (bbsel) {
EM_backbuf_checkAndSelectVerts(vc->em, select);
} else {
- ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
mesh_foreachScreenVert(vc, do_mesh_box_select__doSelectVert, &data, 1);
}
}
@@ -1524,7 +1515,6 @@ static int do_mesh_box_select(ViewContext *vc, rcti *rect, int select, int exten
if(bbsel) {
EM_backbuf_checkAndSelectFaces(vc->em, select);
} else {
- ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
mesh_foreachScreenFace(vc, do_mesh_box_select__doSelectFace, &data);
}
}
@@ -1829,6 +1819,7 @@ void VIEW3D_OT_select_border(wmOperatorType *ot)
ot->exec= view3d_borderselect_exec;
ot->modal= WM_border_select_modal;
ot->poll= view3d_selectable_data;
+ ot->cancel= WM_border_select_cancel;
/* flags */
ot->flag= OPTYPE_UNDO;
@@ -2308,6 +2299,7 @@ void VIEW3D_OT_select_circle(wmOperatorType *ot)
ot->modal= WM_gesture_circle_modal;
ot->exec= view3d_circle_select_exec;
ot->poll= view3d_selectable_data;
+ ot->cancel= WM_gesture_circle_cancel;
/* flags */
ot->flag= OPTYPE_UNDO;
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index 0c4ab161e71..aadb355f743 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -1560,7 +1560,7 @@ static void restore_localviewdata(ScrArea *sa, int free)
}
}
-static void endlocalview(Scene *scene, ScrArea *sa)
+static void endlocalview(Main *bmain, Scene *scene, ScrArea *sa)
{
View3D *v3d= sa->spacedata.first;
struct Base *base;
@@ -1586,6 +1586,8 @@ static void endlocalview(Scene *scene, ScrArea *sa)
base->object->lay= base->lay;
}
}
+
+ DAG_on_visible_update(bmain, FALSE);
}
}
@@ -1594,7 +1596,7 @@ static int localview_exec(bContext *C, wmOperator *UNUSED(unused))
View3D *v3d= CTX_wm_view3d(C);
if(v3d->localvd)
- endlocalview(CTX_data_scene(C), CTX_wm_area(C));
+ endlocalview(CTX_data_main(C), CTX_data_scene(C), CTX_wm_area(C));
else
initlocalview(CTX_data_main(C), CTX_data_scene(C), CTX_wm_area(C));
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index 0ce21c2efee..b8369d8cbff 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -4879,8 +4879,8 @@ void initEdgeSlide(TransInfo *t)
t->idx_max = 0;
t->num.idx_max = 0;
t->snap[0] = 0.0f;
- t->snap[1] = (float)((5.0/180)*M_PI);
- t->snap[2] = t->snap[1] * 0.2f;
+ t->snap[1] = 0.1f;
+ t->snap[2] = t->snap[1] * 0.1f;
t->num.increment = t->snap[1];
@@ -5006,6 +5006,9 @@ int EdgeSlide(TransInfo *t, const int UNUSED(mval[2]))
snapGrid(t, &final);
+ /* only do this so out of range values are not displayed */
+ CLAMP(final, -1.0f, 1.0f);
+
if (hasNumInput(&t->num)) {
char c[20];
@@ -5013,10 +5016,10 @@ int EdgeSlide(TransInfo *t, const int UNUSED(mval[2]))
outputNumInput(&(t->num), c);
- sprintf(str, "Edge Slide Percent: %s", &c[0]);
+ sprintf(str, "Edge Slide: %s", &c[0]);
}
else {
- sprintf(str, "Edge Slide Percent: %.2f", final);
+ sprintf(str, "Edge Slide: %.2f", final);
}
CLAMP(final, -1.0f, 1.0f);
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index 29fc514f01f..e0250829a66 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -4022,6 +4022,7 @@ static void freeSeqData(TransInfo *t)
}
if(overlap) {
+ int has_effect= 0;
for(seq= seqbasep->first; seq; seq= seq->next)
seq->tmp= NULL;
@@ -4030,12 +4031,47 @@ static void freeSeqData(TransInfo *t)
for(a=0; a<t->total; a++, td++) {
seq= ((TransDataSeq *)td->extra)->seq;
if ((seq != seq_prev)) {
- /* Tag seq with a non zero value, used by shuffle_seq_time to identify the ones to shuffle */
- seq->tmp= (void*)1;
+ /* check effects strips, we cant change their time */
+ if((seq->type & SEQ_EFFECT) && seq->seq1) {
+ has_effect= TRUE;
+ }
+ else {
+ /* Tag seq with a non zero value, used by shuffle_seq_time to identify the ones to shuffle */
+ seq->tmp= (void*)1;
+ }
}
}
shuffle_seq_time(seqbasep, t->scene);
+
+ if(has_effect) {
+ /* update effects strips based on strips just moved in time */
+ td= t->data;
+ seq_prev= NULL;
+ for(a=0; a<t->total; a++, td++) {
+ seq= ((TransDataSeq *)td->extra)->seq;
+ if ((seq != seq_prev)) {
+ if((seq->type & SEQ_EFFECT) && seq->seq1) {
+ calc_sequence(t->scene, seq);
+ }
+ }
+ }
+
+ /* now if any effects _still_ overlap, we need to move them up */
+ td= t->data;
+ seq_prev= NULL;
+ for(a=0; a<t->total; a++, td++) {
+ seq= ((TransDataSeq *)td->extra)->seq;
+ if ((seq != seq_prev)) {
+ if((seq->type & SEQ_EFFECT) && seq->seq1) {
+ if(seq_test_overlap(seqbasep, seq)) {
+ shuffle_seq(seqbasep, seq, t->scene);
+ }
+ }
+ }
+ }
+ /* done with effects */
+ }
}
}
#endif
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index 8699eb1cc2d..71ebe5e051c 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -675,8 +675,9 @@ void recalcData(TransInfo *t)
EditMesh *em = ((Mesh*)t->obedit->data)->edit_mesh;
/* mirror modifier clipping? */
if(t->state != TRANS_CANCEL) {
- clipMirrorModifier(t, t->obedit);
+ /* apply clipping after so we never project past the clip plane [#25423] */
applyProject(t);
+ clipMirrorModifier(t, t->obedit);
}
if((t->options & CTX_NO_MIRROR) == 0 && (t->flag & T_MIRROR))
editmesh_apply_to_mirror(t);
diff --git a/source/blender/editors/util/ed_util.c b/source/blender/editors/util/ed_util.c
index 705fb83264c..3dd7514429e 100644
--- a/source/blender/editors/util/ed_util.c
+++ b/source/blender/editors/util/ed_util.c
@@ -106,10 +106,6 @@ void ED_editors_exit(bContext *C)
if(sce->obedit) {
Object *ob= sce->obedit;
- /* global in meshtools... */
- mesh_octree_table(NULL, NULL, NULL, 'e');
- mesh_mirrtopo_table(NULL, 'e');
-
if(ob) {
if(ob->type==OB_MESH) {
Mesh *me= ob->data;
@@ -122,26 +118,13 @@ void ED_editors_exit(bContext *C)
else if(ob->type==OB_ARMATURE) {
ED_armature_edit_free(ob);
}
- else if(ob->type==OB_FONT) {
- // free_editText();
- }
- // else if(ob->type==OB_MBALL)
- // BLI_freelistN(&editelems);
- // free_editLatt();
- // free_posebuf(); // XXX this is still a global...
- }
- }
- else if(sce->basact && sce->basact->object) {
- Object *ob= sce->basact->object;
-
- /* if weight-painting is on, free mesh octree data */
- if(ob->mode & OB_MODE_WEIGHT_PAINT) {
- mesh_octree_table(NULL, NULL, NULL, 'e');
- mesh_mirrtopo_table(NULL, 'e');
}
}
}
-
+
+ /* global in meshtools... */
+ mesh_octree_table(NULL, NULL, NULL, 'e');
+ mesh_mirrtopo_table(NULL, 'e');
}
diff --git a/source/blender/editors/util/editmode_undo.c b/source/blender/editors/util/editmode_undo.c
index 732e5087af2..bcbc134d06d 100644
--- a/source/blender/editors/util/editmode_undo.c
+++ b/source/blender/editors/util/editmode_undo.c
@@ -296,7 +296,7 @@ void undo_editmode_clear(void)
}
/* based on index nr it does a restore */
-static void undo_number(bContext *C, int nr)
+void undo_editmode_number(bContext *C, int nr)
{
UndoElem *uel;
int a=1;
@@ -337,66 +337,28 @@ int undo_editmode_valid(const char *undoname)
return undobase.last != undobase.first;
}
-/* ************** for interaction with menu/pullown */
-void undo_editmode_menu(bContext *C)
+/* get name of undo item, return null if no item with this index */
+/* if active pointer, set it to 1 if true */
+char *undo_editmode_get_name(bContext *C, int nr, int *active)
{
UndoElem *uel;
- DynStr *ds= BLI_dynstr_new();
- short event= 0;
- char *menu;
-
- undo_clean_stack(C); // removes other objects from it
-
- BLI_dynstr_append(ds, "Editmode Undo History %t");
-
- for(uel= undobase.first; uel; uel= uel->next) {
- BLI_dynstr_append(ds, "|");
- BLI_dynstr_append(ds, uel->name);
- }
-
- menu= BLI_dynstr_get_cstring(ds);
- BLI_dynstr_free(ds);
-
-// XXX event= pupmenu_col(menu, 20);
- MEM_freeN(menu);
- if(event>0) undo_number(C, event);
-}
-
-static void do_editmode_undohistorymenu(bContext *C, void *UNUSED(arg), int event)
-{
- Object *obedit= CTX_data_edit_object(C);
-
- if(obedit==NULL || event<1) return;
-
- undo_number(C, event-1);
+ /* prevent wrong numbers to be returned */
+ undo_clean_stack(C);
-}
-
-uiBlock *editmode_undohistorymenu(bContext *C, ARegion *ar, void *UNUSED(arg))
-{
- uiBlock *block;
- UndoElem *uel;
- short yco = 20, menuwidth = 120;
- short item= 1;
+ if(active) *active= 0;
- undo_clean_stack(C); // removes other objects from it
-
- block= uiBeginBlock(C, ar, "view3d_edit_mesh_undohistorymenu", UI_EMBOSSP);
- uiBlockSetButmFunc(block, do_editmode_undohistorymenu, NULL);
-
- for(uel= undobase.first; uel; uel= uel->next, item++) {
- if (uel==curundo) uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, uel->name, 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, (float)item, "");
- if (uel==curundo) uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+ uel= BLI_findlink(&undobase, nr);
+ if(uel) {
+ if(active && uel==curundo)
+ *active= 1;
+ return uel->name;
}
-
- uiBlockSetDirection(block, UI_RIGHT);
- uiTextBoundsBlock(block, 60);
- return block;
+ return NULL;
}
+
void *undo_editmode_get_prev(Object *ob)
{
UndoElem *ue= undobase.last;
diff --git a/source/blender/editors/util/undo.c b/source/blender/editors/util/undo.c
index f4e27a5faf9..8a6ec7f75db 100644
--- a/source/blender/editors/util/undo.c
+++ b/source/blender/editors/util/undo.c
@@ -68,6 +68,9 @@
#include "RNA_access.h"
#include "RNA_define.h"
+#include "UI_interface.h"
+#include "UI_resources.h"
+
#include "util_intern.h"
#define MAXUNDONAME 64 /* XXX, make common define */
@@ -111,10 +114,12 @@ void ED_undo_push(bContext *C, const char *str)
if(wm->file_saved) {
wm->file_saved= 0;
+ /* notifier that data changed, for save-over warning or header */
WM_event_add_notifier(C, NC_WM|ND_DATACHANGED, NULL);
}
}
+/* note: also check undo_history_exec() in bottom if you change notifiers */
static int ed_undo_step(bContext *C, int step, const char *undoname)
{
Object *obedit= CTX_data_edit_object(C);
@@ -151,11 +156,11 @@ static int ed_undo_step(bContext *C, int step, const char *undoname)
int do_glob_undo= 0;
if(obact && obact->mode & OB_MODE_TEXTURE_PAINT) {
- if(!ED_undo_paint_step(C, UNDO_PAINT_IMAGE, step, undoname) && undoname)
+ if(!ED_undo_paint_step(C, UNDO_PAINT_IMAGE, step, undoname))
do_glob_undo= 1;
}
else if(obact && obact->mode & OB_MODE_SCULPT) {
- if(!ED_undo_paint_step(C, UNDO_PAINT_MESH, step, undoname) && undoname)
+ if(!ED_undo_paint_step(C, UNDO_PAINT_MESH, step, undoname))
do_glob_undo= 1;
}
else if(obact && obact->mode & OB_MODE_PARTICLE_EDIT) {
@@ -277,32 +282,6 @@ static int ed_redo_exec(bContext *C, wmOperator *UNUSED(op))
return ed_undo_step(C, -1, NULL);
}
-#if 0 /* UNUSED */
-void ED_undo_menu(bContext *C)
-{
- Object *obedit= CTX_data_edit_object(C);
- Object *obact= CTX_data_active_object(C);
-
- if(obedit) {
- //if ELEM7(obedit->type, OB_MESH, OB_FONT, OB_CURVE, OB_SURF, OB_MBALL, OB_LATTICE, OB_ARMATURE)
- // undo_editmode_menu();
- }
- else {
- if(obact && obact->mode & OB_MODE_PARTICLE_EDIT)
- PE_undo_menu(CTX_data_scene(C), CTX_data_active_object(C));
- else if(U.uiflag & USER_GLOBALUNDO) {
- char *menu= BKE_undo_menu_string();
- if(menu) {
- short event= 0; // XXX pupmenu_col(menu, 20);
- MEM_freeN(menu);
- if(event>0) {
- BKE_undo_number(C, event);
- }
- }
- }
- }
-}
-#endif
/* ********************** */
@@ -328,6 +307,8 @@ void ED_OT_undo_push(wmOperatorType *ot)
/* api callbacks */
ot->exec= ed_undo_push_exec;
+ ot->flag= OPTYPE_INTERNAL;
+
RNA_def_string(ot->srna, "message", "Add an undo step *function may be moved*", MAXUNDONAME, "Undo Message", "");
}
@@ -399,3 +380,144 @@ void ED_undo_operator_repeat_cb_evt(bContext *C, void *arg_op, int UNUSED(arg_ev
{
ED_undo_operator_repeat(C, (wmOperator *)arg_op);
}
+
+
+/* ************************** */
+
+#define UNDOSYSTEM_GLOBAL 1
+#define UNDOSYSTEM_EDITMODE 2
+#define UNDOSYSTEM_PARTICLE 3
+
+static int get_undo_system(bContext *C)
+{
+ Object *obedit= CTX_data_edit_object(C);
+
+ /* find out which undo system */
+ if(obedit) {
+ if (ELEM7(obedit->type, OB_MESH, OB_FONT, OB_CURVE, OB_SURF, OB_MBALL, OB_LATTICE, OB_ARMATURE))
+ return UNDOSYSTEM_EDITMODE;
+ }
+ else {
+ Object *obact= CTX_data_active_object(C);
+
+ if(obact && obact->mode & OB_MODE_PARTICLE_EDIT)
+ return UNDOSYSTEM_PARTICLE;
+ else if(U.uiflag & USER_GLOBALUNDO)
+ return UNDOSYSTEM_GLOBAL;
+ }
+
+ return 0;
+}
+
+/* create enum based on undo items */
+static EnumPropertyItem *rna_undo_itemf(bContext *C, int undosys, int *totitem)
+{
+ EnumPropertyItem item_tmp= {0}, *item= NULL;
+ int active, i= 0;
+
+ while(TRUE) {
+ char *name= NULL;
+
+ if(undosys==UNDOSYSTEM_PARTICLE) {
+ name= PE_undo_get_name(CTX_data_scene(C), i, &active);
+ }
+ else if(undosys==UNDOSYSTEM_EDITMODE) {
+ name= undo_editmode_get_name(C, i, &active);
+ }
+ else {
+ name= BKE_undo_get_name(i, &active);
+ }
+
+ if(name) {
+ item_tmp.identifier= item_tmp.name= name;
+ if(active)
+ item_tmp.icon= ICON_RESTRICT_VIEW_OFF;
+ else
+ item_tmp.icon= ICON_NONE;
+ item_tmp.value= i++;
+ RNA_enum_item_add(&item, totitem, &item_tmp);
+ }
+ else
+ break;
+ }
+
+ RNA_enum_item_end(&item, totitem);
+
+ return item;
+}
+
+
+static int undo_history_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+{
+ int undosys, totitem= 0;
+
+ undosys= get_undo_system(C);
+
+ if(undosys) {
+ EnumPropertyItem *item= rna_undo_itemf(C, undosys, &totitem);
+
+ if(totitem > 0) {
+ uiPopupMenu *pup= uiPupMenuBegin(C, op->type->name, ICON_NONE);
+ uiLayout *layout= uiPupMenuLayout(pup);
+ uiLayout *split= uiLayoutSplit(layout, 0, 0), *column;
+ int i, c;
+
+ for(c=0, i=totitem-1; i >= 0; i--, c++) {
+ if( (c % 20)==0 )
+ column= uiLayoutColumn(split, 0);
+ if(item[i].identifier)
+ uiItemIntO(column, item[i].name, item[i].icon, op->type->idname, "item", item[i].value);
+
+ }
+
+ MEM_freeN(item);
+
+ uiPupMenuEnd(C, pup);
+ }
+
+ }
+ return OPERATOR_CANCELLED;
+}
+
+/* note: also check ed_undo_step() in top if you change notifiers */
+static int undo_history_exec(bContext *C, wmOperator *op)
+{
+ if(RNA_property_is_set(op->ptr, "item")) {
+ int undosys= get_undo_system(C);
+ int item= RNA_int_get(op->ptr, "item");
+
+ if(undosys==UNDOSYSTEM_PARTICLE) {
+ PE_undo_number(CTX_data_scene(C), item);
+ }
+ else if(undosys==UNDOSYSTEM_EDITMODE) {
+ undo_editmode_number(C, item+1);
+ WM_event_add_notifier(C, NC_GEOM|ND_DATA, NULL);
+ }
+ else {
+ BKE_undo_number(C, item);
+ WM_event_add_notifier(C, NC_SCENE|ND_LAYER_CONTENT, CTX_data_scene(C));
+ }
+ WM_event_add_notifier(C, NC_WINDOW, NULL);
+
+ return OPERATOR_FINISHED;
+ }
+ return OPERATOR_CANCELLED;
+}
+
+void ED_OT_undo_history(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Undo History";
+ ot->description= "Redo specific action in history";
+ ot->idname= "ED_OT_undo_history";
+
+ /* api callbacks */
+ ot->invoke= undo_history_invoke;
+ ot->exec= undo_history_exec;
+ ot->poll= ED_operator_screenactive;
+
+ RNA_def_int(ot->srna, "item", 0, 0, INT_MAX, "Item", "", 0, INT_MAX);
+
+}
+
+
diff --git a/source/blender/editors/util/util_intern.h b/source/blender/editors/util/util_intern.h
index 1a82668236d..bfa758b3faa 100644
--- a/source/blender/editors/util/util_intern.h
+++ b/source/blender/editors/util/util_intern.h
@@ -37,8 +37,12 @@
/* internal exports only */
/* editmode_undo.c */
-void undo_editmode_name(bContext *C, const char *undoname);
-int undo_editmode_valid(const char *undoname);
+void undo_editmode_name (struct bContext *C, const char *undoname);
+int undo_editmode_valid (const char *undoname);
+char *undo_editmode_get_name (struct bContext *C, int nr, int *active);
+void *undo_editmode_get_prev (struct Object *ob);
+void undo_editmode_step (struct bContext *C, int step);
+void undo_editmode_number (struct bContext *C, int nr);
#endif /* ED_UTIL_INTERN_H */
diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c
index 66b1e7d412b..c09f8cff02d 100644
--- a/source/blender/editors/uvedit/uvedit_ops.c
+++ b/source/blender/editors/uvedit/uvedit_ops.c
@@ -2221,6 +2221,7 @@ static void UV_OT_select_border(wmOperatorType *ot)
ot->exec= border_select_exec;
ot->modal= WM_border_select_modal;
ot->poll= ED_operator_image_active; /* requires space image */;
+ ot->cancel= WM_border_select_cancel;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
@@ -2310,6 +2311,7 @@ static void UV_OT_circle_select(wmOperatorType *ot)
ot->modal= WM_gesture_circle_modal;
ot->exec= circle_select_exec;
ot->poll= ED_operator_image_active; /* requires space image */;
+ ot->cancel= WM_gesture_circle_cancel;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c
index 0e7df43bd34..7dfbc52819e 100644
--- a/source/blender/gpu/intern/gpu_draw.c
+++ b/source/blender/gpu/intern/gpu_draw.c
@@ -687,9 +687,25 @@ void GPU_paint_update_image(Image *ima, int x, int y, int w, int h, int mipmap)
glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &skip_pixels);
glGetIntegerv(GL_UNPACK_SKIP_ROWS, &skip_rows);
- if ((ibuf->rect==NULL) && ibuf->rect_float)
- IMB_rect_from_float(ibuf);
-
+ if (ibuf->rect_float){
+ /*This case needs a whole new buffer*/
+ if(ibuf->rect==NULL) {
+ IMB_rect_from_float(ibuf);
+ }
+ else {
+ /* Do partial drawing. 'buffer' holds only the changed part. Needed for color corrected result */
+ float *buffer = (float *)MEM_mallocN(w*h*sizeof(float)*4, "temp_texpaint_float_buf");
+ IMB_partial_rect_from_float(ibuf, buffer, x, y, w, h);
+ glBindTexture(GL_TEXTURE_2D, ima->bindcode);
+ glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA,
+ GL_FLOAT, buffer);
+ MEM_freeN(buffer);
+ if(ima->tpageflag & IMA_MIPMAP_COMPLETE)
+ ima->tpageflag &= ~IMA_MIPMAP_COMPLETE;
+ return;
+ }
+ }
+
glBindTexture(GL_TEXTURE_2D, ima->bindcode);
glPixelStorei(GL_UNPACK_ROW_LENGTH, ibuf->x);
diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h
index 21249c9e8f7..5d61452e149 100644
--- a/source/blender/imbuf/IMB_imbuf.h
+++ b/source/blender/imbuf/IMB_imbuf.h
@@ -243,8 +243,15 @@ void IMB_free_anim(struct anim *anim);
*
* @attention Defined in filter.c
*/
+
+#define FILTER_MASK_NULL 0
+#define FILTER_MASK_MARGIN 1
+#define FILTER_MASK_USED 2
+
void IMB_filter(struct ImBuf *ibuf);
void IMB_filterN(struct ImBuf *out, struct ImBuf *in);
+void IMB_mask_filter_extend(char *mask, int width, int height);
+void IMB_mask_clear(struct ImBuf *ibuf, char *mask, int val);
void IMB_filter_extend(struct ImBuf *ibuf, char *mask);
void IMB_makemipmap(struct ImBuf *ibuf, int use_filter);
void IMB_remakemipmap(struct ImBuf *ibuf, int use_filter);
@@ -320,7 +327,12 @@ int imb_get_anim_type(const char *name);
*/
void IMB_de_interlace(struct ImBuf *ibuf);
void IMB_interlace(struct ImBuf *ibuf);
+
+/* create char buffer, color corrected if necessary, for ImBufs that lack one */
void IMB_rect_from_float(struct ImBuf *ibuf);
+/* create char buffer for part of the image, color corrected if necessary,
+ Changed part will be stored in buffer. This is expected to be used for texture painting updates */
+void IMB_partial_rect_from_float(struct ImBuf *ibuf, float *buffer, int x, int y, int w, int h);
void IMB_float_from_rect(struct ImBuf *ibuf);
void IMB_float_from_rect_simple(struct ImBuf *ibuf); /* no profile conversion */
/* note, check that the conversion exists, only some are supported */
diff --git a/source/blender/imbuf/intern/divers.c b/source/blender/imbuf/intern/divers.c
index 6b35d7df397..90ee2692cf0 100644
--- a/source/blender/imbuf/intern/divers.c
+++ b/source/blender/imbuf/intern/divers.c
@@ -197,6 +197,135 @@ void IMB_rect_from_float(struct ImBuf *ibuf)
ibuf->userflags &= ~IB_RECT_INVALID;
}
+
+
+/* converts from linear float to sRGB byte for part of the texture, buffer will hold the changed part */
+void IMB_partial_rect_from_float(struct ImBuf *ibuf,float *buffer, int x, int y, int w, int h)
+{
+ /* indices to source and destination image pixels */
+ float *srcFloatPxl;
+ unsigned char *dstBytePxl;
+ /* buffer index will fill buffer */
+ float *bufferIndex;
+
+ /* convenience pointers to start of image buffers */
+ float *init_srcFloatPxl = (float *)ibuf->rect_float;
+ unsigned char *init_dstBytePxl = (unsigned char *) ibuf->rect;
+
+ /* Dithering factor */
+ float dither= ibuf->dither / 255.0f;
+ /* respective attributes of image */
+ short profile= ibuf->profile;
+ int channels= ibuf->channels;
+
+ int i, j;
+
+ /*
+ if called -only- from GPU_paint_update_image this test will never fail
+ but leaving it here for better or worse
+ */
+ if(init_srcFloatPxl==NULL || (buffer == NULL)){
+ return;
+ }
+ if(init_dstBytePxl==NULL) {
+ imb_addrectImBuf(ibuf);
+ init_dstBytePxl = (unsigned char *) ibuf->rect;
+ }
+ if(channels==1) {
+ for (j = 0; j < h; j++){
+ bufferIndex = buffer + w*j*4;
+ dstBytePxl = init_dstBytePxl + (ibuf->x*(y + j) + x)*4;
+ srcFloatPxl = init_srcFloatPxl + (ibuf->x*(y + j) + x);
+ for(i = 0; i < w; i++, dstBytePxl+=4, srcFloatPxl++, bufferIndex+=4) {
+ dstBytePxl[1]= dstBytePxl[2]= dstBytePxl[3]= dstBytePxl[0] = FTOCHAR(srcFloatPxl[0]);
+ bufferIndex[0] = bufferIndex[1] = bufferIndex[2] = bufferIndex[3] = srcFloatPxl[0];
+ }
+ }
+ }
+ else if (profile == IB_PROFILE_LINEAR_RGB) {
+ if(channels == 3) {
+ for (j = 0; j < h; j++){
+ bufferIndex = buffer + w*j*4;
+ dstBytePxl = init_dstBytePxl + (ibuf->x*(y + j) + x)*4;
+ srcFloatPxl = init_srcFloatPxl + (ibuf->x*(y + j) + x)*3;
+ for(i = 0; i < w; i++, dstBytePxl+=4, srcFloatPxl+=3, bufferIndex += 4) {
+ linearrgb_to_srgb_v3_v3(bufferIndex, srcFloatPxl);
+ F3TOCHAR4(bufferIndex, dstBytePxl);
+ bufferIndex[3]= 1.0;
+ }
+ }
+ }
+ else if (channels == 4) {
+ if (dither != 0.f) {
+ for (j = 0; j < h; j++){
+ bufferIndex = buffer + w*j*4;
+ dstBytePxl = init_dstBytePxl + (ibuf->x*(y + j) + x)*4;
+ srcFloatPxl = init_srcFloatPxl + (ibuf->x*(y + j) + x)*4;
+ for(i = 0; i < w; i++, dstBytePxl+=4, srcFloatPxl+=4, bufferIndex+=4) {
+ const float d = (BLI_frand()-0.5f)*dither;
+ linearrgb_to_srgb_v3_v3(bufferIndex, srcFloatPxl);
+ bufferIndex[3] = srcFloatPxl[3];
+ add_v4_fl(bufferIndex, d);
+ F4TOCHAR4(bufferIndex, dstBytePxl);
+ }
+ }
+ } else {
+ for (j = 0; j < h; j++){
+ bufferIndex = buffer + w*j*4;
+ dstBytePxl = init_dstBytePxl + (ibuf->x*(y + j) + x)*4;
+ srcFloatPxl = init_srcFloatPxl + (ibuf->x*(y + j) + x)*4;
+ for(i = 0; i < w; i++, dstBytePxl+=4, srcFloatPxl+=4, bufferIndex+=4) {
+ linearrgb_to_srgb_v3_v3(bufferIndex, srcFloatPxl);
+ bufferIndex[3]= srcFloatPxl[3];
+ F4TOCHAR4(bufferIndex, dstBytePxl);
+ }
+ }
+ }
+ }
+ }
+ else if(ELEM(profile, IB_PROFILE_NONE, IB_PROFILE_SRGB)) {
+ if(channels==3) {
+ for (j = 0; j < h; j++){
+ bufferIndex = buffer + w*j*4;
+ dstBytePxl = init_dstBytePxl + (ibuf->x*(y + j) + x)*4;
+ srcFloatPxl = init_srcFloatPxl + (ibuf->x*(y + j) + x)*3;
+ for(i = 0; i < w; i++, dstBytePxl+=4, srcFloatPxl+=3, bufferIndex+=4) {
+ copy_v3_v3(bufferIndex, srcFloatPxl);
+ F3TOCHAR4(bufferIndex, dstBytePxl);
+ bufferIndex[3] = 1.0;
+ }
+ }
+ }
+ else {
+ if (dither != 0.f) {
+ for (j = 0; j < h; j++){
+ bufferIndex = buffer + w*j*4;
+ dstBytePxl = init_dstBytePxl + (ibuf->x*(y + j) + x)*4;
+ srcFloatPxl = init_srcFloatPxl + (ibuf->x*(y + j) + x)*4;
+ for(i = 0; i < w; i++, dstBytePxl+=4, srcFloatPxl+=4, bufferIndex+=4) {
+ const float d = (BLI_frand()-0.5f)*dither;
+ copy_v4_v4(bufferIndex, srcFloatPxl);
+ add_v4_fl(bufferIndex,d);
+ F4TOCHAR4(bufferIndex, dstBytePxl);
+ }
+ }
+ } else {
+ for (j = 0; j < h; j++){
+ bufferIndex = buffer + w*j*4;
+ dstBytePxl = init_dstBytePxl + (ibuf->x*(y + j) + x)*4;
+ srcFloatPxl = init_srcFloatPxl + (ibuf->x*(y + j) + x)*4;
+ for(i = 0; i < w; i++, dstBytePxl+=4, srcFloatPxl+=4, bufferIndex+=4) {
+ copy_v4_v4(bufferIndex, srcFloatPxl);
+ F4TOCHAR4(bufferIndex, dstBytePxl);
+ }
+ }
+ }
+ }
+ }
+ /* ensure user flag is reset */
+ ibuf->userflags &= ~IB_RECT_INVALID;
+}
+
static void imb_float_from_rect_nonlinear(struct ImBuf *ibuf, float *fbuf)
{
float *tof = fbuf;
diff --git a/source/blender/imbuf/intern/filter.c b/source/blender/imbuf/intern/filter.c
index 16fb1fdf4aa..d12360e5a7e 100644
--- a/source/blender/imbuf/intern/filter.c
+++ b/source/blender/imbuf/intern/filter.c
@@ -262,6 +262,70 @@ void IMB_filter(struct ImBuf *ibuf)
imb_filterx(ibuf);
}
+void IMB_mask_filter_extend(char *mask, int width, int height)
+{
+ char *row1, *row2, *row3;
+ int rowlen, x, y;
+ char *temprect;
+
+ rowlen= width;
+
+ /* make a copy, to prevent flooding */
+ temprect= MEM_dupallocN(mask);
+
+ for(y=1; y<=height; y++) {
+ /* setup rows */
+ row1= (char *)(temprect + (y-2)*rowlen);
+ row2= row1 + rowlen;
+ row3= row2 + rowlen;
+ if(y==1)
+ row1= row2;
+ else if(y==height)
+ row3= row2;
+
+ for(x=0; x<rowlen; x++) {
+ if (mask[((y-1)*rowlen)+x]==0) {
+ if (*row1 || *row2 || *row3 || *(row1+1) || *(row3+1) ) {
+ mask[((y-1)*rowlen)+x] = FILTER_MASK_MARGIN;
+ } else if((x!=rowlen-1) && (*(row1+2) || *(row2+2) || *(row3+2)) ) {
+ mask[((y-1)*rowlen)+x] = FILTER_MASK_MARGIN;
+ }
+ }
+
+ if(x!=0) {
+ row1++; row2++; row3++;
+ }
+ }
+ }
+
+ MEM_freeN(temprect);
+}
+
+void IMB_mask_clear(ImBuf *ibuf, char *mask, int val)
+{
+ int x,y;
+ if (ibuf->rect_float) {
+ for(x=0; x<ibuf->x; x++) {
+ for(y=0; y<ibuf->y; y++) {
+ if (mask[ibuf->x*y + x] == val) {
+ float *col= ibuf->rect_float + 4*(ibuf->x*y + x);
+ col[0] = col[1] = col[2] = col[3] = 0.0f;
+ }
+ }
+ }
+ } else {
+ /* char buffer */
+ for(x=0; x<ibuf->x; x++) {
+ for(y=0; y<ibuf->y; y++) {
+ if (mask[ibuf->x*y + x] == val) {
+ char *col= (char *)(ibuf->rect + ibuf->x*y + x);
+ col[0] = col[1] = col[2] = col[3] = 0;
+ }
+ }
+ }
+ }
+}
+
#define EXTEND_PIXEL(color, w) if((color)[3]) {r+= w*(color)[0]; g+= w*(color)[1]; b+= w*(color)[2]; a+= w*(color)[3]; tot+=w;}
/* if alpha is zero, it checks surrounding pixels and averages color. sets new alphas to 1.0
diff --git a/source/blender/imbuf/intern/targa.c b/source/blender/imbuf/intern/targa.c
index 5d9f350be48..ec00b15c079 100644
--- a/source/blender/imbuf/intern/targa.c
+++ b/source/blender/imbuf/intern/targa.c
@@ -586,7 +586,7 @@ struct ImBuf *imb_loadtarga(unsigned char *mem, size_t mem_size, int flags)
ibuf->depth = size;
if (tga.mapbits != 32) { /* set alpha bits */
- cmap[0] &= BIG_LONG(0x00ffffff);
+ cmap[0] &= BIG_LONG(0x00ffffffl);
}
}
diff --git a/source/blender/makesdna/DNA_actuator_types.h b/source/blender/makesdna/DNA_actuator_types.h
index 7951ebc8c99..b368aadf4c2 100644
--- a/source/blender/makesdna/DNA_actuator_types.h
+++ b/source/blender/makesdna/DNA_actuator_types.h
@@ -135,7 +135,7 @@ typedef struct bIpoActuator {
typedef struct bCameraActuator {
struct Object *ob;
float height, min, max;
- float pad;
+ float damping;
short pad1, axis;
float pad2;
} bCameraActuator ;
diff --git a/source/blender/makesdna/DNA_lattice_types.h b/source/blender/makesdna/DNA_lattice_types.h
index 662ef9e8a45..a9e745b8148 100644
--- a/source/blender/makesdna/DNA_lattice_types.h
+++ b/source/blender/makesdna/DNA_lattice_types.h
@@ -83,5 +83,7 @@ typedef struct Lattice {
#define LT_DS_EXPAND 4
+#define LT_INDEX(lt, u, v, w) ((w) * ((lt)->pntsu * (lt)->pntsv) + ((v) * (lt)->pntsu) + (u))
+
#endif
diff --git a/source/blender/makesdna/DNA_object_fluidsim.h b/source/blender/makesdna/DNA_object_fluidsim.h
index 6f4c16cb7f3..578bf8dd415 100644
--- a/source/blender/makesdna/DNA_object_fluidsim.h
+++ b/source/blender/makesdna/DNA_object_fluidsim.h
@@ -69,7 +69,7 @@ typedef struct FluidsimSettings {
short viscosityMode;
short viscosityExponent;
/* gravity strength */
- float gravx,gravy,gravz;
+ float grav[3];
/* anim start end time (in seconds) */
float animStart, animEnd;
/* bake start end time (in blender frames) */
@@ -161,6 +161,9 @@ typedef struct FluidsimSettings {
#define OB_FSBND_FREESLIP (1<<(OB_TYPEFLAG_START+4))
#define OB_FSINFLOW_LOCALCOORD (1<<(OB_TYPEFLAG_START+5))
+/* surface generation flag (part of enabling chapter 6 of "Free Surface Flows with Moving and Deforming Objects for LBM") */
+#define OB_FSSG_NOOBS (1<<(OB_TYPEFLAG_START+6))
+
// guiDisplayMode particle flags
#define OB_FSDOM_GEOM 1
#define OB_FSDOM_PREVIEW 2
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index 657bfb1c884..c6fa07482c5 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -253,19 +253,12 @@ typedef struct RenderData {
*/
short yparts;
- short winpos, planes, imtype, subimtype;
-
- /** Mode bits: */
- /* 0: Enable backbuffering for images */
- short bufflag;
- short quality;
+ short planes, imtype, subimtype, quality;
/**
* Render to image editor, fullscreen or to new window.
*/
short displaymode;
-
- short rpad1, rpad2;
/**
* Flags for render settings. Use bit-masking to access the settings.
@@ -322,11 +315,7 @@ typedef struct RenderData {
/**
* Adjustment factors for the aspect ratio in the x direction, was a short in 2.45
*/
- float xasp;
- /**
- * Adjustment factors for the aspect ratio in the x direction, was a short in 2.45
- */
- float yasp;
+ float xasp, yasp;
float frs_sec_base;
@@ -349,8 +338,8 @@ typedef struct RenderData {
short bake_normal_space, bake_quad_split;
float bake_maxdist, bake_biasdist, bake_pad;
- /* paths to backbufffer, output */
- char backbuf[160], pic[160];
+ /* path to render output */
+ char pic[240];
/* stamps flags. */
int stamp;
@@ -1009,13 +998,14 @@ typedef struct Scene {
#define R_JPEG2K_CINE_PRESET 256
#define R_JPEG2K_CINE_48FPS 512
-
/* bake_mode: same as RE_BAKE_xxx defines */
/* bake_flag: */
#define R_BAKE_CLEAR 1
#define R_BAKE_OSA 2
#define R_BAKE_TO_ACTIVE 4
#define R_BAKE_NORMALIZE 8
+#define R_BAKE_MULTIRES 16
+#define R_BAKE_LORES_MESH 32
/* bake_normal_space */
#define R_BAKE_SPACE_CAMERA 0
diff --git a/source/blender/makesdna/DNA_screen_types.h b/source/blender/makesdna/DNA_screen_types.h
index cd19f4cb3de..b52ed35ddce 100644
--- a/source/blender/makesdna/DNA_screen_types.h
+++ b/source/blender/makesdna/DNA_screen_types.h
@@ -187,7 +187,6 @@ typedef struct ARegion {
#define AREA_FLAG_DRAWSPLIT_H 16
#define AREA_FLAG_DRAWSPLIT_V 32
-/* If you change EDGEWIDTH, also do the global arrat edcol[] */
#define EDGEWIDTH 1
#define AREAGRID 4
#define AREAMINX 32
diff --git a/source/blender/makesdna/DNA_sequence_types.h b/source/blender/makesdna/DNA_sequence_types.h
index f89cc9d518a..3e7654bcf47 100644
--- a/source/blender/makesdna/DNA_sequence_types.h
+++ b/source/blender/makesdna/DNA_sequence_types.h
@@ -253,27 +253,30 @@ typedef struct SpeedControlVars {
#define SEQ_NAME_MAXSTR 24
/* seq->flag */
-#define SEQ_LEFTSEL 2
-#define SEQ_RIGHTSEL 4
-#define SEQ_OVERLAP 8
-#define SEQ_FILTERY 16
-#define SEQ_MUTE 32
-#define SEQ_MAKE_PREMUL 64
-#define SEQ_REVERSE_FRAMES 128
-#define SEQ_IPO_FRAME_LOCKED 256
-#define SEQ_EFFECT_NOT_LOADED 512
-#define SEQ_FLAG_DELETE 1024
-#define SEQ_FLIPX 2048
-#define SEQ_FLIPY 4096
-#define SEQ_MAKE_FLOAT 8192
-#define SEQ_LOCK 16384
-#define SEQ_USE_PROXY 32768
-#define SEQ_USE_TRANSFORM 65536
-#define SEQ_USE_CROP 131072
-#define SEQ_USE_COLOR_BALANCE 262144
-#define SEQ_USE_PROXY_CUSTOM_DIR 524288
-#define SEQ_USE_PROXY_CUSTOM_FILE 2097152
-#define SEQ_USE_EFFECT_DEFAULT_FADE 4194304
+#define SEQ_LEFTSEL (1<<1)
+#define SEQ_RIGHTSEL (1<<2)
+#define SEQ_OVERLAP (1<<3)
+#define SEQ_FILTERY (1<<4)
+#define SEQ_MUTE (1<<5)
+#define SEQ_MAKE_PREMUL (1<<6)
+#define SEQ_REVERSE_FRAMES (1<<7)
+#define SEQ_IPO_FRAME_LOCKED (1<<8)
+#define SEQ_EFFECT_NOT_LOADED (1<<9)
+#define SEQ_FLAG_DELETE (1<<10)
+#define SEQ_FLIPX (1<<11)
+#define SEQ_FLIPY (1<<12)
+#define SEQ_MAKE_FLOAT (1<<13)
+#define SEQ_LOCK (1<<14)
+#define SEQ_USE_PROXY (1<<15)
+#define SEQ_USE_TRANSFORM (1<<16)
+#define SEQ_USE_CROP (1<<17)
+#define SEQ_USE_COLOR_BALANCE (1<<18)
+#define SEQ_USE_PROXY_CUSTOM_DIR (1<<19)
+
+#define SEQ_USE_PROXY_CUSTOM_FILE (1<<21)
+#define SEQ_USE_EFFECT_DEFAULT_FADE (1<<22)
+
+#define SEQ_INVALID_EFFECT (1<<31)
/* convenience define for all selection flags */
#define SEQ_ALLSEL (SELECT+SEQ_LEFTSEL+SEQ_RIGHTSEL)
diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h
index a7a04384d3c..cf416bf9d5b 100644
--- a/source/blender/makesdna/DNA_userdef_types.h
+++ b/source/blender/makesdna/DNA_userdef_types.h
@@ -305,7 +305,7 @@ typedef struct UserDef {
int savetime;
char tempdir[160]; // FILE_MAXDIR length
char fontdir[160];
- char renderdir[160];
+ char renderdir[240]; // FILE_MAX length
char textudir[160];
char plugtexdir[160];
char plugseqdir[160];
@@ -374,7 +374,8 @@ typedef struct UserDef {
short scrcastfps; /* frame rate for screencast to be played back */
short scrcastwait; /* milliseconds between screencast snapshots */
- short pad8, pad[3]; /* Value for Dual/Single Column UI */
+ short widget_unit; /* defaults to 20 for 72 DPI setting */
+ short pad[3];
char versemaster[160];
char verseuser[160];
diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h
index e0feba3f2fd..ca19a86e42c 100644
--- a/source/blender/makesrna/RNA_access.h
+++ b/source/blender/makesrna/RNA_access.h
@@ -650,6 +650,7 @@ PropertyType RNA_property_type(PropertyRNA *prop);
PropertySubType RNA_property_subtype(PropertyRNA *prop);
PropertyUnit RNA_property_unit(PropertyRNA *prop);
int RNA_property_flag(PropertyRNA *prop);
+void *RNA_property_py_data_get(PropertyRNA *prop);
int RNA_property_array_length(PointerRNA *ptr, PropertyRNA *prop);
int RNA_property_array_check(PointerRNA *ptr, PropertyRNA *prop);
diff --git a/source/blender/makesrna/RNA_define.h b/source/blender/makesrna/RNA_define.h
index b076393ef3d..ac2a89161d9 100644
--- a/source/blender/makesrna/RNA_define.h
+++ b/source/blender/makesrna/RNA_define.h
@@ -163,6 +163,8 @@ void RNA_def_property_update(PropertyRNA *prop, int noteflag, const char *update
void RNA_def_property_editable_func(PropertyRNA *prop, const char *editable);
void RNA_def_property_editable_array_func(PropertyRNA *prop, const char *editable);
+void RNA_def_property_update_runtime(PropertyRNA *prop, void *func);
+
void RNA_def_property_dynamic_array_funcs(PropertyRNA *prop, const char *getlength);
void RNA_def_property_boolean_funcs(PropertyRNA *prop, const char *get, const char *set);
void RNA_def_property_int_funcs(PropertyRNA *prop, const char *get, const char *set, const char *range);
@@ -172,6 +174,7 @@ void RNA_def_property_string_funcs(PropertyRNA *prop, const char *get, const cha
void RNA_def_property_pointer_funcs(PropertyRNA *prop, const char *get, const char *set, const char *typef, const char *poll);
void RNA_def_property_collection_funcs(PropertyRNA *prop, const char *begin, const char *next, const char *end, const char *get, const char *length, const char *lookupint, const char *lookupstring);
void RNA_def_property_srna(PropertyRNA *prop, const char *type);
+void RNA_def_py_data(PropertyRNA *prop, void *py_data);
/* Function */
diff --git a/source/blender/makesrna/RNA_types.h b/source/blender/makesrna/RNA_types.h
index b3f2ae01c99..ec213d6a496 100644
--- a/source/blender/makesrna/RNA_types.h
+++ b/source/blender/makesrna/RNA_types.h
@@ -159,6 +159,8 @@ typedef enum PropertyFlag {
/* hidden in the user interface */
PROP_HIDDEN = 1<<19,
+ /* do not write in presets */
+ PROP_SKIP_SAVE = 1<<28,
/* function paramater flags */
PROP_REQUIRED = 1<<2,
@@ -190,6 +192,7 @@ typedef enum PropertyFlag {
/* need context for update function */
PROP_CONTEXT_UPDATE = 1<<22,
+ PROP_CONTEXT_PROPERTY_UPDATE = (1<<22)|(1<<27),
/* Use for arrays or for any data that should not have a referene kept
* most common case is functions that return arrays where the array */
diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c
index cc18d8d9d0d..91f88a26987 100644
--- a/source/blender/makesrna/intern/rna_access.c
+++ b/source/blender/makesrna/intern/rna_access.c
@@ -755,6 +755,11 @@ int RNA_property_flag(PropertyRNA *prop)
return rna_ensure_property(prop)->flag;
}
+void *RNA_property_py_data_get(PropertyRNA *prop)
+{
+ return prop->py_data;
+}
+
int RNA_property_array_length(PointerRNA *ptr, PropertyRNA *prop)
{
return rna_ensure_property_array_length(ptr, prop);
@@ -1344,7 +1349,14 @@ static void rna_property_update(bContext *C, Main *bmain, Scene *scene, PointerR
/* ideally no context would be needed for update, but there's some
parts of the code that need it still, so we have this exception */
if(prop->flag & PROP_CONTEXT_UPDATE) {
- if(C) ((ContextUpdateFunc)prop->update)(C, ptr);
+ if(C) {
+ if(prop->flag & PROP_CONTEXT_PROPERTY_UPDATE) {
+ ((ContextPropUpdateFunc)prop->update)(C, ptr, prop);
+ }
+ else {
+ ((ContextUpdateFunc)prop->update)(C, ptr);
+ }
+ }
}
else
prop->update(bmain, scene, ptr);
diff --git a/source/blender/makesrna/intern/rna_actuator.c b/source/blender/makesrna/intern/rna_actuator.c
index 656dbc53656..75c884a5fbb 100644
--- a/source/blender/makesrna/intern/rna_actuator.c
+++ b/source/blender/makesrna/intern/rna_actuator.c
@@ -927,6 +927,13 @@ static void rna_def_camera_actuator(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Max", "");
RNA_def_property_update(prop, NC_LOGIC, NULL);
+ prop= RNA_def_property(srna, "damping", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "damping");
+ RNA_def_property_range(prop, 0, 10.0);
+ RNA_def_property_ui_range(prop, 0, 5.0, 1, 2);
+ RNA_def_property_ui_text(prop, "Damping", "Specify the strength of the constraint that drive the camera behind the target");
+ RNA_def_property_update(prop, NC_LOGIC, NULL);
+
/* x/y */
prop= RNA_def_property(srna, "axis", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "axis");
diff --git a/source/blender/makesrna/intern/rna_camera.c b/source/blender/makesrna/intern/rna_camera.c
index 1705e2e5376..37912f810fc 100644
--- a/source/blender/makesrna/intern/rna_camera.c
+++ b/source/blender/makesrna/intern/rna_camera.c
@@ -133,7 +133,7 @@ void RNA_def_camera(BlenderRNA *brna)
prop= RNA_def_property(srna, "ortho_scale", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "ortho_scale");
- RNA_def_property_range(prop, 0.01f, 1000.0f);
+ RNA_def_property_range(prop, 0.01f, 4000.0f);
RNA_def_property_ui_text(prop, "Orthographic Scale", "Orthographic Camera scale (similar to zoom)");
RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, NULL);
diff --git a/source/blender/makesrna/intern/rna_controller.c b/source/blender/makesrna/intern/rna_controller.c
index 92c762098c7..db5409bf7ef 100644
--- a/source/blender/makesrna/intern/rna_controller.c
+++ b/source/blender/makesrna/intern/rna_controller.c
@@ -87,6 +87,20 @@ static void rna_Controller_type_set(struct PointerRNA *ptr, int value)
}
}
+static void rna_Controller_mode_set(struct PointerRNA *ptr, int value)
+{
+ bController *cont= (bController *)ptr->data;
+ bPythonCont *pycon= (bPythonCont *)cont->data;
+
+ // if mode changed and previous mode were Script
+ if (value != pycon->mode && pycon->mode == CONT_PY_SCRIPT)
+ {
+ // clear script to avoid it to get linked with the controller
+ pycon->text = NULL;
+ }
+ pycon->mode = value;
+}
+
static int rna_Controller_state_number_get(struct PointerRNA *ptr)
{
bController *cont= (bController *)ptr->data;
@@ -222,6 +236,7 @@ void RNA_def_controller(BlenderRNA *brna)
prop= RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, python_controller_modes);
+ RNA_def_property_enum_funcs(prop, NULL, "rna_Controller_mode_set", NULL);
RNA_def_property_ui_text(prop, "Execution Method", "Python script type (textblock or module - faster)");
RNA_def_property_update(prop, NC_LOGIC, NULL);
diff --git a/source/blender/makesrna/intern/rna_define.c b/source/blender/makesrna/intern/rna_define.c
index 66d1036ec44..8e9c7e287d6 100644
--- a/source/blender/makesrna/intern/rna_define.c
+++ b/source/blender/makesrna/intern/rna_define.c
@@ -1839,6 +1839,11 @@ void RNA_def_property_update(PropertyRNA *prop, int noteflag, const char *func)
prop->update= (UpdateFunc)func;
}
+void RNA_def_property_update_runtime(PropertyRNA *prop, void *func)
+{
+ prop->update= func;
+}
+
void RNA_def_property_dynamic_array_funcs(PropertyRNA *prop, const char *getlength)
{
if(!DefRNA.preprocess) {
@@ -2057,6 +2062,11 @@ void RNA_def_property_srna(PropertyRNA *prop, const char *type)
prop->srna= (StructRNA*)type;
}
+void RNA_def_py_data(PropertyRNA *prop, void *py_data)
+{
+ prop->py_data= py_data;
+}
+
/* Compact definitions */
PropertyRNA *RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, int default_value, const char *ui_name, const char *ui_description)
@@ -2822,6 +2832,7 @@ void RNA_def_property_free_pointers(PropertyRNA *prop)
if(prop->identifier) MEM_freeN((void*)prop->identifier);
if(prop->name) MEM_freeN((void*)prop->name);
if(prop->description) MEM_freeN((void*)prop->description);
+ if(prop->py_data) MEM_freeN(prop->py_data);
switch(prop->type) {
case PROP_BOOLEAN: {
diff --git a/source/blender/makesrna/intern/rna_fluidsim.c b/source/blender/makesrna/intern/rna_fluidsim.c
index 7c93ae4168b..1ba2e32502f 100644
--- a/source/blender/makesrna/intern/rna_fluidsim.c
+++ b/source/blender/makesrna/intern/rna_fluidsim.c
@@ -312,7 +312,7 @@ static void rna_def_fluidsim_domain(BlenderRNA *brna)
/* advanced settings */
prop= RNA_def_property(srna, "gravity", PROP_FLOAT, PROP_ACCELERATION);
- RNA_def_property_float_sdna(prop, NULL, "gravx");
+ RNA_def_property_float_sdna(prop, NULL, "grav");
RNA_def_property_array(prop, 3);
RNA_def_property_range(prop, -1000.1, 1000.1);
RNA_def_property_ui_text(prop, "Gravity", "Gravity in X, Y and Z direction");
@@ -384,6 +384,12 @@ static void rna_def_fluidsim_domain(BlenderRNA *brna)
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_ui_text(prop, "Generate Speed Vectors", "Generate speed vectors for vector blur");
+ /* no collision object surface */
+ prop= RNA_def_property(srna, "surface_noobs", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "typeFlags", OB_FSSG_NOOBS);
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_ui_text(prop, "Hide fluid surface", "");
+
/* particles */
prop= RNA_def_property(srna, "tracer_particles", PROP_INT, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_group.c b/source/blender/makesrna/intern/rna_group.c
index a5097cc8b41..5d71d204a72 100644
--- a/source/blender/makesrna/intern/rna_group.c
+++ b/source/blender/makesrna/intern/rna_group.c
@@ -95,7 +95,7 @@ static void rna_def_group_objects(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_function_ui_description(func, "Add this object to a group");
/* object to add */
parm= RNA_def_pointer(func, "object", "Object", "", "Object to add.");
- RNA_def_property_flag(parm, PROP_REQUIRED);
+ RNA_def_property_flag(parm, PROP_REQUIRED|PROP_NEVER_NULL);
/* remove object */
func= RNA_def_function(srna, "unlink", "rna_Group_objects_unlink");
diff --git a/source/blender/makesrna/intern/rna_internal_types.h b/source/blender/makesrna/intern/rna_internal_types.h
index 771d2afcd96..249833ae94b 100644
--- a/source/blender/makesrna/intern/rna_internal_types.h
+++ b/source/blender/makesrna/intern/rna_internal_types.h
@@ -62,6 +62,7 @@ struct Scene;
/* Function Callbacks */
typedef void (*UpdateFunc)(struct Main *main, struct Scene *scene, struct PointerRNA *ptr);
+typedef void (*ContextPropUpdateFunc)(struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop);
typedef void (*ContextUpdateFunc)(struct bContext *C, struct PointerRNA *ptr);
typedef int (*EditableFunc)(struct PointerRNA *ptr);
typedef int (*ItemEditableFunc)(struct PointerRNA *ptr, int index);
@@ -177,6 +178,10 @@ struct PropertyRNA {
* any property can have this but should only be used for collections and arrays
* since python will convert int/bool/pointer's */
struct StructRNA *srna; /* attributes attached directly to this collection */
+
+ /* python handle to hold all callbacks
+ * (in a pointer array at the moment, may later be a tuple) */
+ void *py_data;
};
/* Property Types */
diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c
index 2d3c3fe7a3a..479e449958b 100644
--- a/source/blender/makesrna/intern/rna_mesh.c
+++ b/source/blender/makesrna/intern/rna_mesh.c
@@ -40,6 +40,9 @@
#include "WM_types.h"
+#include "BLI_math_base.h"
+#include "BLI_math_rotation.h"
+
#ifdef RNA_RUNTIME
#include "DNA_scene_types.h"
@@ -912,6 +915,20 @@ static void rna_TextureFace_image_set(PointerRNA *ptr, PointerRNA value)
tf->tpage= (struct Image*)id;
}
+static void rna_Mesh_auto_smooth_angle_set(PointerRNA *ptr, float value)
+{
+ Mesh *me= (Mesh*)ptr->id.data;
+ value= RAD2DEGF(value);
+ CLAMP(value, 1.0f, 80.0f);
+ me->smoothresh= (int)value;
+}
+
+static float rna_Mesh_auto_smooth_angle_get(PointerRNA *ptr)
+{
+ Mesh *me= (Mesh*)ptr->id.data;
+ return DEG2RADF((float)me->smoothresh);
+}
+
static int rna_MeshFace_verts_get_length(PointerRNA *ptr, int length[RNA_MAX_ARRAY_DIMENSION])
{
MFace *face= (MFace*)ptr->data;
@@ -1913,9 +1930,15 @@ static void rna_def_mesh(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flag", ME_AUTOSMOOTH);
RNA_def_property_ui_text(prop, "Auto Smooth", "Treats all set-smoothed faces with angles less than the specified angle as 'smooth' during render");
+#if 1 /* expose as radians */
+ prop= RNA_def_property(srna, "auto_smooth_angle", PROP_FLOAT, PROP_ANGLE);
+ RNA_def_property_float_funcs(prop, "rna_Mesh_auto_smooth_angle_get", "rna_Mesh_auto_smooth_angle_set", NULL);
+ RNA_def_property_ui_range(prop, DEG2RAD(1.0), DEG2RAD(80), 1.0, 1);
+#else
prop= RNA_def_property(srna, "auto_smooth_angle", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "smoothresh");
RNA_def_property_range(prop, 1, 80);
+#endif
RNA_def_property_ui_text(prop, "Auto Smooth Angle", "Defines maximum angle between face normals that 'Auto Smooth' will operate on");
prop= RNA_def_property(srna, "show_double_sided", PROP_BOOLEAN, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index 75f3f1ef238..ff277b6d9b0 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -578,6 +578,34 @@ static void rna_UVProjectModifier_num_projectors_set(PointerRNA *ptr, int value)
md->projectors[a]= NULL;
}
+static float rna_EdgeSplitModifier_split_angle_get(PointerRNA *ptr)
+{
+ EdgeSplitModifierData *md= (EdgeSplitModifierData*)ptr->data;
+ return DEG2RADF(md->split_angle);
+}
+
+static void rna_EdgeSplitModifier_split_angle_set(PointerRNA *ptr, float value)
+{
+ EdgeSplitModifierData *md= (EdgeSplitModifierData*)ptr->data;
+ value= RAD2DEGF(value);
+ CLAMP(value, 0.0f, 180.0f);
+ md->split_angle= (int)value;
+}
+
+static float rna_BevelModifier_angle_limit_get(PointerRNA *ptr)
+{
+ BevelModifierData *md= (BevelModifierData*)ptr->data;
+ return DEG2RADF(md->bevel_angle);
+}
+
+static void rna_BevelModifier_angle_limit_set(PointerRNA *ptr, float value)
+{
+ BevelModifierData *md= (BevelModifierData*)ptr->data;
+ value= RAD2DEGF(value);
+ CLAMP(value, 0.0f, 180.0f);
+ md->bevel_angle= (int)value;
+}
+
#else
static void rna_def_property_subdivision_common(StructRNA *srna, const char type[])
@@ -1365,10 +1393,16 @@ static void rna_def_modifier_edgesplit(BlenderRNA *brna)
RNA_def_struct_sdna(srna, "EdgeSplitModifierData");
RNA_def_struct_ui_icon(srna, ICON_MOD_EDGESPLIT);
- // XXX, convert to radians.
+#if 1 /* expose as radians */
+ prop= RNA_def_property(srna, "split_angle", PROP_FLOAT, PROP_ANGLE);
+ RNA_def_property_float_funcs(prop, "rna_EdgeSplitModifier_split_angle_get", "rna_EdgeSplitModifier_split_angle_set", NULL);
+ RNA_def_property_range(prop, 0, DEG2RAD(180));
+ RNA_def_property_ui_range(prop, 0, DEG2RAD(180), 100, 2);
+#else
prop= RNA_def_property(srna, "split_angle", PROP_FLOAT, PROP_NONE);
RNA_def_property_range(prop, 0, 180);
RNA_def_property_ui_range(prop, 0, 180, 100, 2);
+#endif
RNA_def_property_ui_text(prop, "Split Angle", "Angle above which to split edges");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
@@ -1965,10 +1999,17 @@ static void rna_def_modifier_bevel(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Edge Weight Method", "What edge weight to use for weighting a vertex");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
+#if 1 /* expose as radians */
+ prop= RNA_def_property(srna, "angle_limit", PROP_FLOAT, PROP_ANGLE);
+ RNA_def_property_float_funcs(prop, "rna_BevelModifier_angle_limit_get", "rna_BevelModifier_angle_limit_set", NULL);
+ RNA_def_property_range(prop, 0, DEG2RAD(180));
+ RNA_def_property_ui_range(prop, 0, DEG2RAD(180), 100, 2);
+#else
prop= RNA_def_property(srna, "angle_limit", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "bevel_angle");
RNA_def_property_range(prop, 0, 180);
RNA_def_property_ui_range(prop, 0, 180, 100, 2);
+#endif
RNA_def_property_ui_text(prop, "Angle", "Angle above which to bevel edges");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
}
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index d0b60c7f153..7fd6a9dacfe 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -2221,6 +2221,7 @@ static void def_cmp_colorbalance(StructRNA *srna)
RNA_def_property_float_sdna(prop, NULL, "gamma");
RNA_def_property_array(prop, 3);
RNA_def_property_float_array_default(prop, default_1);
+ RNA_def_property_range(prop, 0.f, FLT_MAX);
RNA_def_property_ui_range(prop, 0, 2, 0.1, 3);
RNA_def_property_ui_text(prop, "Power", "Correction for Midtones");
RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update");
@@ -2229,6 +2230,7 @@ static void def_cmp_colorbalance(StructRNA *srna)
RNA_def_property_float_sdna(prop, NULL, "gain");
RNA_def_property_array(prop, 3);
RNA_def_property_float_array_default(prop, default_1);
+ RNA_def_property_range(prop, 0.f, FLT_MAX);
RNA_def_property_ui_range(prop, 0, 2, 0.1, 3);
RNA_def_property_ui_text(prop, "Slope", "Correction for Highlights");
RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update");
diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c
index 9305380d06c..8ee8652e2e5 100644
--- a/source/blender/makesrna/intern/rna_object.c
+++ b/source/blender/makesrna/intern/rna_object.c
@@ -454,6 +454,14 @@ static void rna_Object_dup_group_set(PointerRNA *ptr, PointerRNA value)
BKE_report(NULL, RPT_ERROR, "Cannot set dupli-group as object belongs in group being instanced thus causing a cycle");
}
+void rna_VertexGroup_name_set(PointerRNA *ptr, const char *value)
+{
+ Object *ob= (Object *)ptr->id.data;
+ bDeformGroup *dg= (bDeformGroup *)ptr->data;
+ BLI_strncpy(dg->name, value, sizeof(dg->name));
+ defgroup_unique_name(dg, ob);
+}
+
static int rna_VertexGroup_index_get(PointerRNA *ptr)
{
Object *ob= (Object*)ptr->id.data;
@@ -1236,6 +1244,7 @@ static void rna_def_vertex_group(BlenderRNA *brna)
prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
RNA_def_property_ui_text(prop, "Name", "Vertex group name");
RNA_def_struct_name_property(srna, prop);
+ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_VertexGroup_name_set");
RNA_def_property_update(prop, NC_GEOM|ND_DATA|NA_RENAME, "rna_Object_internal_update_data"); /* update data because modifiers may use [#24761] */
prop= RNA_def_property(srna, "index", PROP_INT, PROP_UNSIGNED);
diff --git a/source/blender/makesrna/intern/rna_rna.c b/source/blender/makesrna/intern/rna_rna.c
index 84bb624b546..b4da3a02442 100644
--- a/source/blender/makesrna/intern/rna_rna.c
+++ b/source/blender/makesrna/intern/rna_rna.c
@@ -493,6 +493,13 @@ static int rna_Property_is_hidden_get(PointerRNA *ptr)
return prop->flag & PROP_HIDDEN ? 1:0;
}
+static int rna_Property_is_skip_save_get(PointerRNA *ptr)
+{
+ PropertyRNA *prop= (PropertyRNA*)ptr->data;
+ return prop->flag & PROP_SKIP_SAVE ? 1:0;
+}
+
+
static int rna_Property_is_enum_flag_get(PointerRNA *ptr)
{
PropertyRNA *prop= (PropertyRNA*)ptr->data;
@@ -1037,6 +1044,11 @@ static void rna_def_property(BlenderRNA *brna)
RNA_def_property_boolean_funcs(prop, "rna_Property_is_hidden_get", NULL);
RNA_def_property_ui_text(prop, "Hidden", "True when the property is hidden");
+ prop= RNA_def_property(srna, "is_skip_save", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_property_boolean_funcs(prop, "rna_Property_is_skip_save_get", NULL);
+ RNA_def_property_ui_text(prop, "Skip Save", "True when the property is not saved in presets");
+
prop= RNA_def_property(srna, "is_output", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_boolean_funcs(prop, "rna_Property_use_output_get", NULL);
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index 72ec09a61fe..145a58ecf0f 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -2812,6 +2812,14 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
RNA_def_property_range(prop, 0.0, 1000.0);
RNA_def_property_ui_text(prop, "Bias", "Bias towards faces further away from the object (in blender units)");
+ prop= RNA_def_property(srna, "use_bake_multires", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "bake_flag", R_BAKE_MULTIRES);
+ RNA_def_property_ui_text(prop, "Bake from Multires", "Bake directly from multires object");
+
+ prop= RNA_def_property(srna, "use_bake_lores_mesh", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "bake_flag", R_BAKE_LORES_MESH);
+ RNA_def_property_ui_text(prop, "Low Resolution Mesh", "Calculate heights against unsubdivided low resolution mesh");
+
/* stamp */
prop= RNA_def_property(srna, "use_stamp_time", PROP_BOOLEAN, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_sequencer.c b/source/blender/makesrna/intern/rna_sequencer.c
index 4171189d928..8c4e4d9e736 100644
--- a/source/blender/makesrna/intern/rna_sequencer.c
+++ b/source/blender/makesrna/intern/rna_sequencer.c
@@ -680,6 +680,23 @@ static void rna_SequenceEditor_overlay_frame_set(PointerRNA *ptr, int value)
ed->over_ofs= value;
}
+
+static void rna_WipeSequence_angle_set(PointerRNA *ptr, float value)
+{
+ Sequence *seq= (Sequence *)(ptr->data);
+ value= RAD2DEGF(value);
+ CLAMP(value, -90.0f, 90.0f);
+ ((WipeVars *)seq->effectdata)->angle= value;
+}
+
+static float rna_WipeSequence_angle_get(PointerRNA *ptr)
+{
+ Sequence *seq= (Sequence *)(ptr->data);
+
+ return DEG2RADF(((WipeVars *)seq->effectdata)->angle);
+}
+
+
#else
static void rna_def_strip_element(BlenderRNA *brna)
@@ -1460,10 +1477,16 @@ static void rna_def_wipe(BlenderRNA *brna)
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Blur Width", "Width of the blur edge, in percentage relative to the image size");
RNA_def_property_update(prop, NC_SCENE|ND_SEQUENCER, "rna_Sequence_update");
-
+
+#if 1 /* expose as radians */
+ prop= RNA_def_property(srna, "angle", PROP_FLOAT, PROP_ANGLE);
+ RNA_def_property_float_funcs(prop, "rna_WipeSequence_angle_get", "rna_WipeSequence_angle_set", NULL);
+ RNA_def_property_range(prop, DEG2RAD(-90.0f), DEG2RAD(90.0f));
+#else
prop= RNA_def_property(srna, "angle", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "angle");
RNA_def_property_range(prop, -90.0f, 90.0f);
+#endif
RNA_def_property_ui_text(prop, "Angle", "Edge angle");
RNA_def_property_update(prop, NC_SCENE|ND_SEQUENCER, "rna_Sequence_update");
diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c
index 3a80207ba15..9e3a31ddb2e 100644
--- a/source/blender/makesrna/intern/rna_texture.c
+++ b/source/blender/makesrna/intern/rna_texture.c
@@ -135,6 +135,7 @@ static void rna_Texture_update(Main *bmain, Scene *scene, PointerRNA *ptr)
DAG_id_tag_update(&tex->id, 0);
WM_main_add_notifier(NC_TEXTURE, tex);
+ WM_main_add_notifier(NC_MATERIAL|ND_SHADING_DRAW, NULL);
}
static void rna_Texture_voxeldata_update(Main *bmain, Scene *scene, PointerRNA *ptr)
diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c
index 12df0b5dbd7..cb50b99c05d 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -69,6 +69,13 @@ static void rna_userdef_update(Main *UNUSED(bmain), Scene *UNUSED(scene), Pointe
WM_main_add_notifier(NC_WINDOW, NULL);
}
+static void rna_userdef_dpi_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+{
+ U.widget_unit = (U.dpi * 20 + 36)/72;
+ WM_main_add_notifier(NC_WINDOW, NULL); /* full redraw */
+ WM_main_add_notifier(NC_SCREEN|NA_EDITED, NULL); /* refresh region sizes */
+}
+
static void rna_userdef_show_manipulator_update(Main *bmain, Scene *scene, PointerRNA *ptr)
{
UserDef *userdef = (UserDef *)ptr->data;
@@ -238,6 +245,13 @@ static void rna_UserDef_weight_color_update(Main *bmain, Scene *scene, PointerRN
static void rna_UserDef_viewport_lights_update(Main *bmain, Scene *scene, PointerRNA *ptr)
{
+ /* if all lights are off gpu_draw resets them all, [#27627]
+ * so disallow them all to be disabled */
+ if(U.light[0].flag==0 && U.light[1].flag==0 && U.light[2].flag==0) {
+ SolidLight *light= ptr->data;
+ light->flag |= 1;
+ }
+
WM_main_add_notifier(NC_SPACE|ND_SPACE_VIEW3D|NS_VIEW3D_GPU, NULL);
rna_userdef_update(bmain, scene, ptr);
}
@@ -2444,7 +2458,7 @@ static void rna_def_userdef_system(BlenderRNA *brna)
RNA_def_property_int_sdna(prop, NULL, "dpi");
RNA_def_property_range(prop, 48, 128);
RNA_def_property_ui_text(prop, "DPI", "Font size and resolution for display");
- RNA_def_property_update(prop, 0, "rna_userdef_update");
+ RNA_def_property_update(prop, 0, "rna_userdef_dpi_update");
prop= RNA_def_property(srna, "scrollback", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "scrollback");
diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c
index 406ee6b3f3e..7ea4701dec3 100644
--- a/source/blender/makesrna/intern/rna_wm.c
+++ b/source/blender/makesrna/intern/rna_wm.c
@@ -272,10 +272,11 @@ EnumPropertyItem keymap_modifiers_items[] = {
EnumPropertyItem operator_flag_items[] = {
{OPTYPE_REGISTER, "REGISTER", 0, "Register", ""},
{OPTYPE_UNDO, "UNDO", 0, "Undo", ""},
- {OPTYPE_BLOCKING, "BLOCKING", 0, "Finished", ""},
+ {OPTYPE_BLOCKING, "BLOCKING", 0, "Blocking", ""},
{OPTYPE_MACRO, "MACRO", 0, "Macro", ""},
{OPTYPE_GRAB_POINTER, "GRAB_POINTER", 0, "Grab Pointer", ""},
{OPTYPE_PRESET, "PRESET", 0, "Preset", ""},
+ {OPTYPE_INTERNAL, "INTERNAL", 0, "Internal", ""},
{0, NULL, 0, NULL, NULL}};
EnumPropertyItem operator_return_items[] = {
@@ -1047,6 +1048,7 @@ static StructRNA* rna_MacroOperator_refine(PointerRNA *opr)
static wmKeyMapItem *rna_KeyMap_item_new(wmKeyMap *km, ReportList *reports, const char *idname, int type, int value, int any, int shift, int ctrl, int alt, int oskey, int keymodifier)
{
// wmWindowManager *wm = CTX_wm_manager(C);
+ char idname_bl[OP_MAX_TYPENAME];
int modifier= 0;
/* only on non-modal maps */
@@ -1055,6 +1057,8 @@ static wmKeyMapItem *rna_KeyMap_item_new(wmKeyMap *km, ReportList *reports, cons
return NULL;
}
+ WM_operator_bl_idname(idname_bl, idname);
+
if(shift) modifier |= KM_SHIFT;
if(ctrl) modifier |= KM_CTRL;
if(alt) modifier |= KM_ALT;
@@ -1062,7 +1066,7 @@ static wmKeyMapItem *rna_KeyMap_item_new(wmKeyMap *km, ReportList *reports, cons
if(any) modifier = KM_ANY;
- return WM_keymap_add_item(km, idname, type, value, modifier, keymodifier);
+ return WM_keymap_add_item(km, idname_bl, type, value, modifier, keymodifier);
}
static wmKeyMapItem *rna_KeyMap_item_new_modal(wmKeyMap *km, bContext *C, ReportList *reports, const char *propvalue_str, int type, int value, int any, int shift, int ctrl, int alt, int oskey, int keymodifier)
diff --git a/source/blender/modifiers/CMakeLists.txt b/source/blender/modifiers/CMakeLists.txt
index cf66a27bda2..348e2a0ec1d 100644
--- a/source/blender/modifiers/CMakeLists.txt
+++ b/source/blender/modifiers/CMakeLists.txt
@@ -88,8 +88,12 @@ set(SRC
if(WITH_MOD_BOOLEAN)
add_definitions(-DWITH_MOD_BOOLEAN)
- list(APPEND SRC intern/MOD_boolean_util.c)
- list(APPEND INC ../../../intern/bsp/extern)
+ list(APPEND SRC
+ intern/MOD_boolean_util.c
+ )
+ list(APPEND INC
+ ../../../intern/bsp/extern
+ )
endif()
if(WITH_MOD_DECIMATE)
diff --git a/source/blender/modifiers/intern/MOD_cloth.c b/source/blender/modifiers/intern/MOD_cloth.c
index 30ddb3f7b9c..1d2a6b2f788 100644
--- a/source/blender/modifiers/intern/MOD_cloth.c
+++ b/source/blender/modifiers/intern/MOD_cloth.c
@@ -190,6 +190,19 @@ static void freeData(ModifierData *md)
}
}
+static void foreachIDLink(ModifierData *md, Object *ob,
+ IDWalkFunc walk, void *userData)
+{
+ ClothModifierData *clmd = (ClothModifierData*) md;
+
+ if(clmd->coll_parms) {
+ walk(userData, ob, (ID **)&clmd->coll_parms->group);
+ }
+
+ if(clmd->sim_parms && clmd->sim_parms->effector_weights) {
+ walk(userData, ob, (ID **)&clmd->sim_parms->effector_weights->group);
+ }
+}
ModifierTypeInfo modifierType_Cloth = {
/* name */ "Cloth",
@@ -215,5 +228,5 @@ ModifierTypeInfo modifierType_Cloth = {
/* dependsOnTime */ dependsOnTime,
/* dependsOnNormals */ NULL,
/* foreachObjectLink */ NULL,
- /* foreachIDLink */ NULL,
+ /* foreachIDLink */ foreachIDLink,
};
diff --git a/source/blender/modifiers/intern/MOD_explode.c b/source/blender/modifiers/intern/MOD_explode.c
index f1bc0d33fd8..10bcbee6661 100644
--- a/source/blender/modifiers/intern/MOD_explode.c
+++ b/source/blender/modifiers/intern/MOD_explode.c
@@ -779,11 +779,11 @@ static DerivedMesh * explodeMesh(ExplodeModifierData *emd,
ParticleSettings *part=psmd->psys->part;
ParticleSimulationData sim= {NULL};
ParticleData *pa=NULL, *pars=psmd->psys->particles;
- ParticleKey state;
+ ParticleKey state, birth;
EdgeHash *vertpahash;
EdgeHashIterator *ehi;
float *vertco= NULL, imat[4][4];
- float loc0[3], nor[3];
+ float rot[4];
float cfra;
/* float timestep; */
int *facepa=emd->facepa;
@@ -814,7 +814,7 @@ static DerivedMesh * explodeMesh(ExplodeModifierData *emd,
for (i=0; i<totface; i++) {
/* do mindex + totvert to ensure the vertex index to be the first
* with BLI_edgehashIterator_getKey */
- if(facepa[i]==totpart || cfra <= (pars+facepa[i])->time)
+ if(facepa[i]==totpart || cfra < (pars+facepa[i])->time)
mindex = totvert+totpart;
else
mindex = totvert+facepa[i];
@@ -868,26 +868,26 @@ static DerivedMesh * explodeMesh(ExplodeModifierData *emd,
/* get particle */
pa= pars+i;
- /* get particle state */
- psys_particle_on_emitter(psmd,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,loc0,nor,NULL,NULL,NULL,NULL);
- mul_m4_v3(ob->obmat,loc0);
+ psys_get_birth_coordinates(&sim, pa, &birth, 0, 0);
state.time=cfra;
psys_get_particle_state(&sim, i, &state, 1);
vertco=CDDM_get_vert(explode,v)->co;
-
mul_m4_v3(ob->obmat,vertco);
- VECSUB(vertco,vertco,loc0);
+ sub_v3_v3(vertco, birth.co);
/* apply rotation, size & location */
- mul_qt_v3(state.rot,vertco);
+ sub_qt_qtqt(rot, state.rot, birth.rot);
+ mul_qt_v3(rot, vertco);
+
if(emd->flag & eExplodeFlag_PaSize)
mul_v3_fl(vertco,pa->size);
- VECADD(vertco,vertco,state.co);
- mul_m4_v3(imat,vertco);
+ add_v3_v3(vertco, state.co);
+
+ mul_m4_v3(imat, vertco);
}
}
BLI_edgehashIterator_free(ehi);
@@ -911,7 +911,7 @@ static DerivedMesh * explodeMesh(ExplodeModifierData *emd,
orig_v4 = source.v4;
- if(facepa[i]!=totpart && cfra <= pa->time)
+ if(facepa[i]!=totpart && cfra < pa->time)
mindex = totvert+totpart;
else
mindex = totvert+facepa[i];
diff --git a/source/blender/modifiers/intern/MOD_fluidsim_util.c b/source/blender/modifiers/intern/MOD_fluidsim_util.c
index 61345427d1c..277f0852f90 100644
--- a/source/blender/modifiers/intern/MOD_fluidsim_util.c
+++ b/source/blender/modifiers/intern/MOD_fluidsim_util.c
@@ -90,10 +90,10 @@ void fluidsim_init(FluidsimModifierData *fluidmd)
fss->viscosityValue = 1.0;
fss->viscosityExponent = 6;
- // dg TODO: change this to []
- fss->gravx = 0.0;
- fss->gravy = 0.0;
- fss->gravz = -9.81;
+ fss->grav[0] = 0.0;
+ fss->grav[1] = 0.0;
+ fss->grav[2] = -9.81;
+
fss->animStart = 0.0;
fss->animEnd = 4.0;
fss->gstar = 0.005; // used as normgstar
@@ -111,7 +111,7 @@ void fluidsim_init(FluidsimModifierData *fluidmd)
// no bounding box needed
// todo - reuse default init from elbeem!
- fss->typeFlags = OB_FSBND_PARTSLIP;
+ fss->typeFlags = OB_FSBND_PARTSLIP | OB_FSSG_NOOBS;
fss->domainNovecgen = 0;
fss->volumeInitType = 1; // volume
fss->partSlipValue = 0.2;
diff --git a/source/blender/modifiers/intern/MOD_mask.c b/source/blender/modifiers/intern/MOD_mask.c
index b36d6848533..94442d96367 100644
--- a/source/blender/modifiers/intern/MOD_mask.c
+++ b/source/blender/modifiers/intern/MOD_mask.c
@@ -45,6 +45,7 @@
#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
+#include "BKE_action.h" /* get_pose_channel */
#include "BKE_cdderivedmesh.h"
#include "BKE_mesh.h"
#include "BKE_modifier.h"
@@ -102,7 +103,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
DerivedMesh *dm= derivedData, *result= NULL;
GHash *vertHash=NULL, *edgeHash, *faceHash;
GHashIterator *hashIter;
- MDeformVert *dvert= NULL;
+ MDeformVert *dvert= NULL, *dv;
int numFaces=0, numEdges=0, numVerts=0;
int maxVerts, maxEdges, maxFaces;
int i;
@@ -130,50 +131,46 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
/* if mode is to use selected armature bones, aggregate the bone groups */
if (mmd->mode == MOD_MASK_MODE_ARM) /* --- using selected bones --- */
{
- GHash *vgroupHash, *boneHash;
+ GHash *vgroupHash;
Object *oba= mmd->ob_arm;
bPoseChannel *pchan;
bDeformGroup *def;
+ char *bone_select_array;
+ int bone_select_tot= 0;
/* check that there is armature object with bones to use, otherwise return original mesh */
- if (ELEM(NULL, mmd->ob_arm, mmd->ob_arm->pose))
- return derivedData;
-
+ if (ELEM3(NULL, mmd->ob_arm, mmd->ob_arm->pose, ob->defbase.first))
+ return derivedData;
+
+ bone_select_array= MEM_mallocN(BLI_countlist(&ob->defbase) * sizeof(char), "mask array");
+
+ for (i = 0, def = ob->defbase.first; def; def = def->next, i++)
+ {
+ if (((pchan= get_pose_channel(oba->pose, def->name)) && pchan->bone && (pchan->bone->flag & BONE_SELECTED)))
+ {
+ bone_select_array[i]= TRUE;
+ bone_select_tot++;
+ }
+ else {
+ bone_select_array[i]= FALSE;
+ }
+ }
+
/* hashes for finding mapping of:
* - vgroups to indices -> vgroupHash (string, int)
* - bones to vgroup indices -> boneHash (index of vgroup, dummy)
*/
vgroupHash= BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp, "mask vgroup gh");
- boneHash= BLI_ghash_new(BLI_ghashutil_inthash, BLI_ghashutil_intcmp, "mask bone gh");
/* build mapping of names of vertex groups to indices */
for (i = 0, def = ob->defbase.first; def; def = def->next, i++)
BLI_ghash_insert(vgroupHash, def->name, SET_INT_IN_POINTER(i));
- /* get selected-posechannel <-> vertexgroup index mapping */
- for (pchan= oba->pose->chanbase.first; pchan; pchan= pchan->next)
- {
- /* check if bone is selected */
- // TODO: include checks for visibility too?
- // FIXME: the depsgraph needs extensions to make this work in realtime...
- if ( (pchan->bone) && (pchan->bone->flag & BONE_SELECTED) )
- {
- /* check if hash has group for this bone */
- if (BLI_ghash_haskey(vgroupHash, pchan->name))
- {
- int defgrp_index= GET_INT_FROM_POINTER(BLI_ghash_lookup(vgroupHash, pchan->name));
-
- /* add index to hash (store under key only) */
- BLI_ghash_insert(boneHash, SET_INT_IN_POINTER(defgrp_index), pchan);
- }
- }
- }
-
/* if no bones selected, free hashes and return original mesh */
- if (BLI_ghash_size(boneHash) == 0)
+ if (bone_select_tot == 0)
{
BLI_ghash_free(vgroupHash, NULL, NULL);
- BLI_ghash_free(boneHash, NULL, NULL);
+ MEM_freeN(bone_select_array);
return derivedData;
}
@@ -183,7 +180,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
if (dvert == NULL)
{
BLI_ghash_free(vgroupHash, NULL, NULL);
- BLI_ghash_free(boneHash, NULL, NULL);
+ MEM_freeN(bone_select_array);
return derivedData;
}
@@ -192,28 +189,29 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
vertHash= BLI_ghash_new(BLI_ghashutil_inthash, BLI_ghashutil_intcmp, "mask vert gh");
/* add vertices which exist in vertexgroups into vertHash for filtering */
- for (i = 0; i < maxVerts; i++)
+ for (i= 0, dv= dvert; i < maxVerts; i++, dv++)
{
- MDeformWeight *def_weight = NULL;
+ MDeformWeight *dw= dv->dw;
int j;
-
- for (j= 0; j < dvert[i].totweight; j++)
+
+ for (j= dv->totweight; j > 0; j--, dw++)
{
- if (BLI_ghash_haskey(boneHash, SET_INT_IN_POINTER(dvert[i].dw[j].def_nr)))
+ if (bone_select_array[dw->def_nr])
{
- def_weight = &dvert[i].dw[j];
- break;
+ if(dw->weight != 0.0f) {
+ break;
+ }
}
}
/* check if include vert in vertHash */
if (mmd->flag & MOD_MASK_INV) {
/* if this vert is in the vgroup, don't include it in vertHash */
- if (def_weight) continue;
+ if (dw) continue;
}
else {
/* if this vert isn't in the vgroup, don't include it in vertHash */
- if (!def_weight) continue;
+ if (!dw) continue;
}
/* add to ghash for verts (numVerts acts as counter for mapping) */
@@ -223,7 +221,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
/* free temp hashes */
BLI_ghash_free(vgroupHash, NULL, NULL);
- BLI_ghash_free(boneHash, NULL, NULL);
+ MEM_freeN(bone_select_array);
}
else /* --- Using Nominated VertexGroup only --- */
{
@@ -241,28 +239,18 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
vertHash= BLI_ghash_new(BLI_ghashutil_inthash, BLI_ghashutil_intcmp, "mask vert2 bh");
/* add vertices which exist in vertexgroup into ghash for filtering */
- for (i = 0; i < maxVerts; i++)
+ for (i= 0, dv= dvert; i < maxVerts; i++, dv++)
{
- MDeformWeight *def_weight = NULL;
- int j;
-
- for (j= 0; j < dvert[i].totweight; j++)
- {
- if (dvert[i].dw[j].def_nr == defgrp_index)
- {
- def_weight = &dvert[i].dw[j];
- break;
- }
- }
+ const int weight_set= defvert_find_weight(dv, defgrp_index) != 0.0f;
/* check if include vert in vertHash */
if (mmd->flag & MOD_MASK_INV) {
/* if this vert is in the vgroup, don't include it in vertHash */
- if (def_weight) continue;
+ if (weight_set) continue;
}
else {
/* if this vert isn't in the vgroup, don't include it in vertHash */
- if (!def_weight) continue;
+ if (!weight_set) continue;
}
/* add to ghash for verts (numVerts acts as counter for mapping) */
diff --git a/source/blender/modifiers/intern/MOD_meshdeform.c b/source/blender/modifiers/intern/MOD_meshdeform.c
index ba73f3fa0d1..5021f3a6d2e 100644
--- a/source/blender/modifiers/intern/MOD_meshdeform.c
+++ b/source/blender/modifiers/intern/MOD_meshdeform.c
@@ -72,6 +72,8 @@ static void freeData(ModifierData *md)
if(mmd->dyngrid) MEM_freeN(mmd->dyngrid);
if(mmd->dyninfluences) MEM_freeN(mmd->dyninfluences);
if(mmd->dynverts) MEM_freeN(mmd->dynverts);
+ if(mmd->bindweights) MEM_freeN(mmd->bindweights); /* deprecated */
+ if(mmd->bindcos) MEM_freeN(mmd->bindcos); /* deprecated */
}
static void copyData(ModifierData *md, ModifierData *target)
diff --git a/source/blender/modifiers/intern/MOD_none.c b/source/blender/modifiers/intern/MOD_none.c
index 489733c8480..48c5b9a4c08 100644
--- a/source/blender/modifiers/intern/MOD_none.c
+++ b/source/blender/modifiers/intern/MOD_none.c
@@ -57,7 +57,7 @@ ModifierTypeInfo modifierType_None = {
/* name */ "None",
/* structName */ "ModifierData",
/* structSize */ sizeof(ModifierData),
- /* type */ eModifierType_None,
+ /* type */ eModifierTypeType_None,
/* flags */ eModifierTypeFlag_AcceptsMesh
| eModifierTypeFlag_AcceptsCVs,
diff --git a/source/blender/modifiers/intern/MOD_smoke.c b/source/blender/modifiers/intern/MOD_smoke.c
index d8e94e92bfa..b6203bb3c1d 100644
--- a/source/blender/modifiers/intern/MOD_smoke.c
+++ b/source/blender/modifiers/intern/MOD_smoke.c
@@ -43,6 +43,7 @@
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_smoke_types.h"
+#include "DNA_object_force.h"
#include "BLI_utildefines.h"
@@ -156,6 +157,10 @@ static void foreachIDLink(ModifierData *md, Object *ob,
walk(userData, ob, (ID **)&smd->domain->coll_group);
walk(userData, ob, (ID **)&smd->domain->fluid_group);
walk(userData, ob, (ID **)&smd->domain->eff_group);
+
+ if(smd->domain->effector_weights) {
+ walk(userData, ob, (ID **)&smd->domain->effector_weights->group);
+ }
}
}
diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_math.c b/source/blender/nodes/intern/CMP_nodes/CMP_math.c
index 4348fd18759..b7a67f3563b 100644
--- a/source/blender/nodes/intern/CMP_nodes/CMP_math.c
+++ b/source/blender/nodes/intern/CMP_nodes/CMP_math.c
@@ -140,7 +140,12 @@ static void do_math(bNode *node, float *out, float *in, float *in2)
break;
case 14: /* Round */
{
- out[0]= (out[0]<0)?(int)(in[0] - 0.5f):(int)(in[0] + 0.5f);
+ /* round by the second value */
+ if( in2[0] != 0.0f )
+ out[0]= floorf(in[0] / in2[0] + 0.5f) * in2[0];
+ else
+ out[0]= floorf(in[0] + 0.5f);
+
}
break;
case 15: /* Less Than */
diff --git a/source/blender/nodes/intern/CMP_util.c b/source/blender/nodes/intern/CMP_util.c
index 78025f4d964..b73a46c7d7d 100644
--- a/source/blender/nodes/intern/CMP_util.c
+++ b/source/blender/nodes/intern/CMP_util.c
@@ -1320,6 +1320,12 @@ void IIR_gauss(CompBuf* src, float sigma, int chan, int xy)
if ((xy < 1) || (xy > 3)) xy = 3;
+ // XXX The YVV macro defined below explicitely expects sources of at least 3x3 pixels,
+ // so just skiping blur along faulty direction if src's def is below that limit!
+ if (src->x < 3) xy &= ~(int) 1;
+ if (src->y < 3) xy &= ~(int) 2;
+ if (xy < 1) return;
+
// see "Recursive Gabor Filtering" by Young/VanVliet
// all factors here in double.prec. Required, because for single.prec it seems to blow up if sigma > ~200
if (sigma >= 3.556)
diff --git a/source/blender/nodes/intern/SHD_nodes/SHD_material.c b/source/blender/nodes/intern/SHD_nodes/SHD_material.c
index 8b477af0689..f66df9bba90 100644
--- a/source/blender/nodes/intern/SHD_nodes/SHD_material.c
+++ b/source/blender/nodes/intern/SHD_nodes/SHD_material.c
@@ -209,6 +209,17 @@ static void node_shader_init_material(bNode* node)
node->custom1= SH_NODE_MAT_DIFF|SH_NODE_MAT_SPEC;
}
+/* XXX this is also done as a local static function in gpu_codegen.c,
+ * but we need this to hack around the crappy material node.
+ */
+static GPUNodeLink *gpu_get_input_link(GPUNodeStack *in)
+{
+ if (in->link)
+ return in->link;
+ else
+ return GPU_uniform(in->vec);
+}
+
static int gpu_shader_material(GPUMaterial *mat, bNode *node, GPUNodeStack *in, GPUNodeStack *out)
{
if(node->id) {
@@ -229,18 +240,18 @@ static int gpu_shader_material(GPUMaterial *mat, bNode *node, GPUNodeStack *in,
/* write values */
if(hasinput[MAT_IN_COLOR])
- shi.rgb = in[MAT_IN_COLOR].link;
+ shi.rgb = gpu_get_input_link(&in[MAT_IN_COLOR]);
if(hasinput[MAT_IN_SPEC])
- shi.specrgb = in[MAT_IN_SPEC].link;
+ shi.specrgb = gpu_get_input_link(&in[MAT_IN_SPEC]);
if(hasinput[MAT_IN_REFL])
- shi.refl = in[MAT_IN_REFL].link;
+ shi.refl = gpu_get_input_link(&in[MAT_IN_REFL]);
/* retrieve normal */
if(hasinput[MAT_IN_NORMAL]) {
GPUNodeLink *tmp;
- shi.vn = in[MAT_IN_NORMAL].link;
+ shi.vn = gpu_get_input_link(&in[MAT_IN_NORMAL]);
GPU_link(mat, "vec_math_normalize", shi.vn, &shi.vn, &tmp);
}
@@ -250,11 +261,11 @@ static int gpu_shader_material(GPUMaterial *mat, bNode *node, GPUNodeStack *in,
if (node->type == SH_NODE_MATERIAL_EXT) {
if(hasinput[MAT_IN_AMB])
- shi.amb= in[MAT_IN_AMB].link;
+ shi.amb= gpu_get_input_link(&in[MAT_IN_AMB]);
if(hasinput[MAT_IN_EMIT])
- shi.emit= in[MAT_IN_EMIT].link;
+ shi.emit= gpu_get_input_link(&in[MAT_IN_EMIT]);
if(hasinput[MAT_IN_ALPHA])
- shi.alpha= in[MAT_IN_ALPHA].link;
+ shi.alpha= gpu_get_input_link(&in[MAT_IN_ALPHA]);
}
GPU_shaderesult_set(&shi, &shr); /* clears shr */
diff --git a/source/blender/python/intern/bpy_driver.c b/source/blender/python/intern/bpy_driver.c
index 6f124d959cb..dec393bd1e4 100644
--- a/source/blender/python/intern/bpy_driver.c
+++ b/source/blender/python/intern/bpy_driver.c
@@ -185,12 +185,11 @@ float BPY_driver_exec(ChannelDriver *driver)
expr_vars= PyTuple_GET_ITEM(((PyObject *)driver->expr_comp), 1);
Py_XDECREF(expr_vars);
- /* intern the arg names so creating the namespace for every run is faster */
expr_vars= PyTuple_New(BLI_countlist(&driver->variables));
PyTuple_SET_ITEM(((PyObject *)driver->expr_comp), 1, expr_vars);
for (dvar= driver->variables.first, i=0; dvar; dvar= dvar->next) {
- PyTuple_SET_ITEM(expr_vars, i++, PyUnicode_InternFromString(dvar->name));
+ PyTuple_SET_ITEM(expr_vars, i++, PyUnicode_FromString(dvar->name));
}
driver->flag &= ~DRIVER_FLAG_RENAMEVAR;
@@ -211,7 +210,7 @@ float BPY_driver_exec(ChannelDriver *driver)
/* try to add to dictionary */
/* if (PyDict_SetItemString(driver_vars, dvar->name, driver_arg)) { */
- if (PyDict_SetItem(driver_vars, PyTuple_GET_ITEM(expr_vars, i++), driver_arg) < 0) { /* use string interning for faster namespace creation */
+ if (PyDict_SetItem(driver_vars, PyTuple_GET_ITEM(expr_vars, i++), driver_arg) < 0) {
/* this target failed - bad name */
if (targets_ok) {
/* first one - print some extra info for easier identification */
diff --git a/source/blender/python/intern/bpy_props.c b/source/blender/python/intern/bpy_props.c
index 4fef084f093..8ed4e41de3e 100644
--- a/source/blender/python/intern/bpy_props.c
+++ b/source/blender/python/intern/bpy_props.c
@@ -47,15 +47,22 @@
#include "../generic/py_capi_utils.h"
+/* initial definition of callback slots we'll probably have more then 1 */
+#define BPY_DATA_CB_SLOT_SIZE 1
+
+#define BPY_DATA_CB_SLOT_UPDATE 0
+
extern BPy_StructRNA *bpy_context_module;
static EnumPropertyItem property_flag_items[]= {
{PROP_HIDDEN, "HIDDEN", 0, "Hidden", ""},
+ {PROP_SKIP_SAVE, "SKIP_SAVE", 0, "Skip Save", ""},
{PROP_ANIMATABLE, "ANIMATABLE", 0, "Animateable", ""},
{0, NULL, 0, NULL, NULL}};
static EnumPropertyItem property_flag_enum_items[]= {
{PROP_HIDDEN, "HIDDEN", 0, "Hidden", ""},
+ {PROP_SKIP_SAVE, "SKIP_SAVE", 0, "Skip Save", ""},
{PROP_ANIMATABLE, "ANIMATABLE", 0, "Animateable", ""},
{PROP_ENUM_FLAG, "ENUM_FLAG", 0, "Enum Flag", ""},
{0, NULL, 0, NULL, NULL}};
@@ -110,6 +117,45 @@ static PyObject *pymeth_PointerProperty= NULL;
static PyObject *pymeth_CollectionProperty= NULL;
static PyObject *pymeth_RemoveProperty= NULL;
+PyObject *pyrna_struct_as_instance(PointerRNA *ptr)
+{
+ PyObject *self= NULL;
+ /* first get self */
+ /* operators can store their own instance for later use */
+ if(ptr->data) {
+ void **instance= RNA_struct_instance(ptr);
+
+ if(instance) {
+ if(*instance) {
+ self= *instance;
+ Py_INCREF(self);
+ }
+ }
+ }
+
+ /* in most cases this will run */
+ if(self == NULL) {
+ self= pyrna_struct_CreatePyObject(ptr);
+ }
+
+ return self;
+}
+
+/* could be moved into bpy_utils */
+static void printf_func_error(PyObject *py_func)
+{
+ /* since we return to C code we can't leave the error */
+ PyCodeObject *f_code= (PyCodeObject *)PyFunction_GET_CODE(py_func);
+ PyErr_Print();
+ PyErr_Clear();
+
+ /* use py style error */
+ fprintf(stderr, "File \"%s\", line %d, in %s\n",
+ _PyUnicode_AsString(f_code->co_filename),
+ f_code->co_firstlineno,
+ _PyUnicode_AsString(((PyFunctionObject *)py_func)->func_name)
+ );
+}
/* operators and classes use this so it can store the args given but defer
* running it until the operator runs where these values are used to setup
@@ -130,6 +176,96 @@ static PyObject *bpy_prop_deferred_return(PyObject *func, PyObject *kw)
return ret;
}
+/* callbacks */
+void bpy_prop_update_cb(struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop)
+{
+ PyGILState_STATE gilstate;
+ PyObject **py_data= (PyObject **)RNA_property_py_data_get(prop);
+ PyObject *py_func;
+ PyObject *args;
+ PyObject *self;
+ PyObject *ret;
+ const int is_write_ok= pyrna_write_check();
+
+ BLI_assert(py_data != NULL);
+
+ if(!is_write_ok) {
+ pyrna_write_set(TRUE);
+ }
+
+ bpy_context_set(C, &gilstate);
+
+ py_func= py_data[BPY_DATA_CB_SLOT_UPDATE];
+
+ args= PyTuple_New(2);
+ self= pyrna_struct_as_instance(ptr);
+ PyTuple_SET_ITEM(args, 0, self);
+
+ PyTuple_SET_ITEM(args, 1, (PyObject *)bpy_context_module);
+ Py_INCREF(bpy_context_module);
+
+ ret= PyObject_CallObject(py_func, args);
+
+ Py_DECREF(args);
+
+ if(ret == NULL) {
+ printf_func_error(py_func);
+ }
+ else {
+ if(ret != Py_None) {
+ PyErr_SetString(PyExc_ValueError, "the return value must be None");
+ printf_func_error(py_func);
+ }
+
+ Py_DECREF(ret);
+ }
+
+ bpy_context_clear(C, &gilstate);
+
+ if(!is_write_ok) {
+ pyrna_write_set(FALSE);
+ }
+}
+
+static int bpy_prop_callback_check(PyObject *py_func, int argcount)
+{
+ if(py_func) {
+ if(!PyFunction_Check(py_func)) {
+ PyErr_Format(PyExc_TypeError,
+ "update keyword: expected a function type, not a %.200s",
+ Py_TYPE(py_func)->tp_name);
+ return -1;
+ }
+ else {
+ PyCodeObject *f_code= (PyCodeObject *)PyFunction_GET_CODE(py_func);
+ if (f_code->co_argcount != argcount) {
+ PyErr_Format(PyExc_TypeError,
+ "update keyword: expected a function taking %d arguments, not %d",
+ argcount, f_code->co_argcount);
+ return -1;
+ }
+ }
+ }
+
+ return 0;
+}
+
+
+static int bpy_prop_callback_assign(struct PropertyRNA *prop, PyObject *update_cb)
+{
+ /* assume this is already checked for type and arg length */
+ if(update_cb) {
+ PyObject **py_data= MEM_callocN(sizeof(PyObject *) * BPY_DATA_CB_SLOT_SIZE, "bpy_prop_callback_assign");
+ RNA_def_property_update_runtime(prop, (void *)bpy_prop_update_cb);
+ py_data[BPY_DATA_CB_SLOT_UPDATE]= update_cb;
+ RNA_def_py_data(prop, py_data);
+
+ RNA_def_property_flag(prop, PROP_CONTEXT_PROPERTY_UPDATE);
+ }
+
+ return 0;
+}
+
/* this define runs at the start of each function and deals with
* returning a deferred property (to be registered later) */
#define BPY_PROPDEF_HEAD(_func) \
@@ -156,11 +292,15 @@ static PyObject *bpy_prop_deferred_return(PyObject *func, PyObject *kw)
* calls because of static strins passed to pyrna_set_to_enum_bitfield */
#define BPY_PROPDEF_CHECK(_func, _property_flag_items) \
if(id_len >= MAX_IDPROP_NAME) { \
- PyErr_Format(PyExc_TypeError, #_func"(): '%.200s' too long, max length is %d", id, MAX_IDPROP_NAME-1); \
+ PyErr_Format(PyExc_TypeError, \
+ #_func"(): '%.200s' too long, max length is %d", \
+ id, MAX_IDPROP_NAME-1); \
return NULL; \
} \
if(RNA_def_property_free_identifier(srna, id) == -1) { \
- PyErr_Format(PyExc_TypeError, #_func"(): '%s' is defined as a non-dynamic type", id); \
+ PyErr_Format(PyExc_TypeError, \
+ #_func"(): '%s' is defined as a non-dynamic type", \
+ id); \
return NULL; \
} \
if(pyopts && pyrna_set_to_enum_bitfield(_property_flag_items, pyopts, &opts, #_func"(options={...}):")) \
@@ -169,7 +309,9 @@ static PyObject *bpy_prop_deferred_return(PyObject *func, PyObject *kw)
#define BPY_PROPDEF_SUBTYPE_CHECK(_func, _property_flag_items, _subtype) \
BPY_PROPDEF_CHECK(_func, _property_flag_items) \
if(pysubtype && RNA_enum_value_from_id(_subtype, pysubtype, &subtype)==0) { \
- PyErr_Format(PyExc_TypeError, #_func"(subtype='%s'): invalid subtype", pysubtype); \
+ PyErr_Format(PyExc_TypeError, \
+ #_func"(subtype='%s'): invalid subtype", \
+ pysubtype); \
return NULL; \
} \
@@ -184,6 +326,11 @@ static PyObject *bpy_prop_deferred_return(PyObject *func, PyObject *kw)
" :type description: string\n" \
+#define BPY_PROPDEF_UPDATE_DOC \
+" :arg update: function to be called when this value is modified,\n" \
+" This function must take 2 values (self, context) and return None.\n" \
+" :type update: function\n" \
+
#if 0
static int bpy_struct_id_used(StructRNA *srna, char *identifier)
{
@@ -197,16 +344,17 @@ static int bpy_struct_id_used(StructRNA *srna, char *identifier)
/* Function that sets RNA, NOTE - self is NULL when called from python, but being abused from C so we can pass the srna allong
* This isnt incorrect since its a python object - but be careful */
PyDoc_STRVAR(BPy_BoolProperty_doc,
-".. function:: BoolProperty(name=\"\", description=\"\", default=False, options={'ANIMATABLE'}, subtype='NONE')\n"
+".. function:: BoolProperty(name=\"\", description=\"\", default=False, options={'ANIMATABLE'}, subtype='NONE', update=None)\n"
"\n"
" Returns a new boolean property definition.\n"
"\n"
BPY_PROPDEF_NAME_DOC
BPY_PROPDEF_DESC_DOC
-" :arg options: Enumerator in ['HIDDEN', 'ANIMATABLE'].\n"
+" :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE'].\n"
" :type options: set\n"
" :arg subtype: Enumerator in ['UNSIGNED', 'PERCENTAGE', 'FACTOR', 'ANGLE', 'TIME', 'DISTANCE', 'NONE'].\n"
" :type subtype: string\n"
+BPY_PROPDEF_UPDATE_DOC
);
static PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw)
{
@@ -215,7 +363,7 @@ static PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw)
BPY_PROPDEF_HEAD(BoolProperty)
if(srna) {
- static const char *kwlist[]= {"attr", "name", "description", "default", "options", "subtype", NULL};
+ static const char *kwlist[]= {"attr", "name", "description", "default", "options", "subtype", "update", NULL};
const char *id=NULL, *name="", *description="";
int id_len;
int def=0;
@@ -224,18 +372,24 @@ static PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw)
int opts=0;
char *pysubtype= NULL;
int subtype= PROP_NONE;
+ PyObject *update_cb= NULL;
if (!PyArg_ParseTupleAndKeywords(args, kw,
- "s#|ssiO!s:BoolProperty",
+ "s#|ssiO!sO:BoolProperty",
(char **)kwlist, &id, &id_len,
&name, &description, &def,
- &PySet_Type, &pyopts, &pysubtype))
+ &PySet_Type, &pyopts, &pysubtype,
+ &update_cb))
{
return NULL;
}
BPY_PROPDEF_SUBTYPE_CHECK(BoolProperty, property_flag_items, property_subtype_number_items)
+ if (bpy_prop_callback_check(update_cb, 2) == -1) {
+ return NULL;
+ }
+
prop= RNA_def_property(srna, id, PROP_BOOLEAN, subtype);
RNA_def_property_boolean_default(prop, def);
RNA_def_property_ui_text(prop, name, description);
@@ -244,6 +398,7 @@ static PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw)
if(opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
if((opts & PROP_ANIMATABLE)==0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
}
+ bpy_prop_callback_assign(prop, update_cb);
RNA_def_property_duplicate_pointers(srna, prop);
}
@@ -251,7 +406,7 @@ static PyObject *BPy_BoolProperty(PyObject *self, PyObject *args, PyObject *kw)
}
PyDoc_STRVAR(BPy_BoolVectorProperty_doc,
-".. function:: BoolVectorProperty(name=\"\", description=\"\", default=(False, False, False), options={'ANIMATABLE'}, subtype='NONE', size=3)\n"
+".. function:: BoolVectorProperty(name=\"\", description=\"\", default=(False, False, False), options={'ANIMATABLE'}, subtype='NONE', size=3, update=None)\n"
"\n"
" Returns a new vector boolean property definition.\n"
"\n"
@@ -259,12 +414,13 @@ BPY_PROPDEF_NAME_DOC
BPY_PROPDEF_DESC_DOC
" :arg default: sequence of booleans the length of *size*.\n"
" :type default: sequence\n"
-" :arg options: Enumerator in ['HIDDEN', 'ANIMATABLE'].\n"
+" :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE'].\n"
" :type options: set\n"
" :arg subtype: Enumerator in ['COLOR', 'TRANSLATION', 'DIRECTION', 'VELOCITY', 'ACCELERATION', 'MATRIX', 'EULER', 'QUATERNION', 'AXISANGLE', 'XYZ', 'COLOR_GAMMA', 'LAYER', 'NONE'].\n"
" :type subtype: string\n"
" :arg size: Vector dimensions in [1, and " STRINGIFY(PYRNA_STACK_ARRAY) "].\n"
" :type size: int\n"
+BPY_PROPDEF_UPDATE_DOC
);
static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject *kw)
{
@@ -273,7 +429,7 @@ static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject
BPY_PROPDEF_HEAD(BoolVectorProperty)
if(srna) {
- static const char *kwlist[]= {"attr", "name", "description", "default", "options", "subtype", "size", NULL};
+ static const char *kwlist[]= {"attr", "name", "description", "default", "options", "subtype", "size", "update", NULL};
const char *id=NULL, *name="", *description="";
int id_len;
int def[PYRNA_STACK_ARRAY]={0};
@@ -284,12 +440,14 @@ static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject
int opts=0;
char *pysubtype= NULL;
int subtype= PROP_NONE;
+ PyObject *update_cb= NULL;
if (!PyArg_ParseTupleAndKeywords(args, kw,
- "s#|ssOO!si:BoolVectorProperty",
+ "s#|ssOO!siO:BoolVectorProperty",
(char **)kwlist, &id, &id_len,
&name, &description, &pydef,
- &PySet_Type, &pyopts, &pysubtype,&size))
+ &PySet_Type, &pyopts, &pysubtype, &size,
+ &update_cb))
{
return NULL;
}
@@ -304,6 +462,10 @@ static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject
if(pydef && PyC_AsArray(def, pydef, size, &PyBool_Type, "BoolVectorProperty(default=sequence)") < 0)
return NULL;
+ if (bpy_prop_callback_check(update_cb, 2) == -1) {
+ return NULL;
+ }
+
// prop= RNA_def_boolean_array(srna, id, size, pydef ? def:NULL, name, description);
prop= RNA_def_property(srna, id, PROP_BOOLEAN, subtype);
RNA_def_property_array(prop, size);
@@ -314,6 +476,7 @@ static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject
if(opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
if((opts & PROP_ANIMATABLE)==0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
}
+ bpy_prop_callback_assign(prop, update_cb);
RNA_def_property_duplicate_pointers(srna, prop);
}
@@ -321,16 +484,17 @@ static PyObject *BPy_BoolVectorProperty(PyObject *self, PyObject *args, PyObject
}
PyDoc_STRVAR(BPy_IntProperty_doc,
-".. function:: IntProperty(name=\"\", description=\"\", default=0, min=-sys.maxint, max=sys.maxint, soft_min=-sys.maxint, soft_max=sys.maxint, step=1, options={'ANIMATABLE'}, subtype='NONE')\n"
+".. function:: IntProperty(name=\"\", description=\"\", default=0, min=-sys.maxint, max=sys.maxint, soft_min=-sys.maxint, soft_max=sys.maxint, step=1, options={'ANIMATABLE'}, subtype='NONE', update=None)\n"
"\n"
" Returns a new int property definition.\n"
"\n"
BPY_PROPDEF_NAME_DOC
BPY_PROPDEF_DESC_DOC
-" :arg options: Enumerator in ['HIDDEN', 'ANIMATABLE'].\n"
+" :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE'].\n"
" :type options: set\n"
" :arg subtype: Enumerator in ['UNSIGNED', 'PERCENTAGE', 'FACTOR', 'ANGLE', 'TIME', 'DISTANCE', 'NONE'].\n"
" :type subtype: string\n"
+BPY_PROPDEF_UPDATE_DOC
);
static PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw)
{
@@ -339,7 +503,7 @@ static PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw)
BPY_PROPDEF_HEAD(IntProperty)
if(srna) {
- static const char *kwlist[]= {"attr", "name", "description", "default", "min", "max", "soft_min", "soft_max", "step", "options", "subtype", NULL};
+ static const char *kwlist[]= {"attr", "name", "description", "default", "min", "max", "soft_min", "soft_max", "step", "options", "subtype", "update", NULL};
const char *id=NULL, *name="", *description="";
int id_len;
int min=INT_MIN, max=INT_MAX, soft_min=INT_MIN, soft_max=INT_MAX, step=1, def=0;
@@ -348,19 +512,25 @@ static PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw)
int opts=0;
char *pysubtype= NULL;
int subtype= PROP_NONE;
+ PyObject *update_cb= NULL;
if (!PyArg_ParseTupleAndKeywords(args, kw,
- "s#|ssiiiiiiO!s:IntProperty",
+ "s#|ssiiiiiiO!sO:IntProperty",
(char **)kwlist, &id, &id_len,
&name, &description, &def,
&min, &max, &soft_min, &soft_max,
- &step, &PySet_Type, &pyopts, &pysubtype))
+ &step, &PySet_Type, &pyopts, &pysubtype,
+ &update_cb))
{
return NULL;
}
BPY_PROPDEF_SUBTYPE_CHECK(IntProperty, property_flag_items, property_subtype_number_items)
+ if (bpy_prop_callback_check(update_cb, 2) == -1) {
+ return NULL;
+ }
+
prop= RNA_def_property(srna, id, PROP_INT, subtype);
RNA_def_property_int_default(prop, def);
RNA_def_property_range(prop, min, max);
@@ -371,13 +541,14 @@ static PyObject *BPy_IntProperty(PyObject *self, PyObject *args, PyObject *kw)
if(opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
if((opts & PROP_ANIMATABLE)==0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
}
+ bpy_prop_callback_assign(prop, update_cb);
RNA_def_property_duplicate_pointers(srna, prop);
}
Py_RETURN_NONE;
}
PyDoc_STRVAR(BPy_IntVectorProperty_doc,
-".. function:: IntVectorProperty(name=\"\", description=\"\", default=(0, 0, 0), min=-sys.maxint, max=sys.maxint, soft_min=-sys.maxint, soft_max=sys.maxint, options={'ANIMATABLE'}, subtype='NONE', size=3)\n"
+".. function:: IntVectorProperty(name=\"\", description=\"\", default=(0, 0, 0), min=-sys.maxint, max=sys.maxint, soft_min=-sys.maxint, soft_max=sys.maxint, options={'ANIMATABLE'}, subtype='NONE', size=3, update=None)\n"
"\n"
" Returns a new vector int property definition.\n"
"\n"
@@ -385,12 +556,13 @@ BPY_PROPDEF_NAME_DOC
BPY_PROPDEF_DESC_DOC
" :arg default: sequence of ints the length of *size*.\n"
" :type default: sequence\n"
-" :arg options: Enumerator in ['HIDDEN', 'ANIMATABLE'].\n"
+" :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE'].\n"
" :type options: set\n"
" :arg subtype: Enumerator in ['COLOR', 'TRANSLATION', 'DIRECTION', 'VELOCITY', 'ACCELERATION', 'MATRIX', 'EULER', 'QUATERNION', 'AXISANGLE', 'XYZ', 'COLOR_GAMMA', 'LAYER', 'NONE'].\n"
" :type subtype: string\n"
" :arg size: Vector dimensions in [1, and " STRINGIFY(PYRNA_STACK_ARRAY) "].\n"
" :type size: int\n"
+BPY_PROPDEF_UPDATE_DOC
);
static PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject *kw)
{
@@ -399,7 +571,7 @@ static PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject
BPY_PROPDEF_HEAD(IntVectorProperty)
if(srna) {
- static const char *kwlist[]= {"attr", "name", "description", "default", "min", "max", "soft_min", "soft_max", "step", "options", "subtype", "size", NULL};
+ static const char *kwlist[]= {"attr", "name", "description", "default", "min", "max", "soft_min", "soft_max", "step", "options", "subtype", "size", "update", NULL};
const char *id=NULL, *name="", *description="";
int id_len;
int min=INT_MIN, max=INT_MAX, soft_min=INT_MIN, soft_max=INT_MAX, step=1, def[PYRNA_STACK_ARRAY]={0};
@@ -410,14 +582,16 @@ static PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject
int opts=0;
char *pysubtype= NULL;
int subtype= PROP_NONE;
+ PyObject *update_cb= NULL;
if (!PyArg_ParseTupleAndKeywords(args, kw,
- "s#|ssOiiiiiO!si:IntVectorProperty",
+ "s#|ssOiiiiiO!siO:IntVectorProperty",
(char **)kwlist, &id, &id_len,
&name, &description, &pydef,
&min, &max, &soft_min, &soft_max,
&step, &PySet_Type, &pyopts,
- &pysubtype, &size))
+ &pysubtype, &size,
+ &update_cb))
{
return NULL;
}
@@ -432,6 +606,10 @@ static PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject
if(pydef && PyC_AsArray(def, pydef, size, &PyLong_Type, "IntVectorProperty(default=sequence)") < 0)
return NULL;
+ if (bpy_prop_callback_check(update_cb, 2) == -1) {
+ return NULL;
+ }
+
prop= RNA_def_property(srna, id, PROP_INT, subtype);
RNA_def_property_array(prop, size);
if(pydef) RNA_def_property_int_array_default(prop, def);
@@ -443,6 +621,7 @@ static PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject
if(opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
if((opts & PROP_ANIMATABLE)==0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
}
+ bpy_prop_callback_assign(prop, update_cb);
RNA_def_property_duplicate_pointers(srna, prop);
}
Py_RETURN_NONE;
@@ -450,18 +629,19 @@ static PyObject *BPy_IntVectorProperty(PyObject *self, PyObject *args, PyObject
PyDoc_STRVAR(BPy_FloatProperty_doc,
-".. function:: FloatProperty(name=\"\", description=\"\", default=0.0, min=sys.float_info.min, max=sys.float_info.max, soft_min=sys.float_info.min, soft_max=sys.float_info.max, step=3, precision=2, options={'ANIMATABLE'}, subtype='NONE', unit='NONE')\n"
+".. function:: FloatProperty(name=\"\", description=\"\", default=0.0, min=sys.float_info.min, max=sys.float_info.max, soft_min=sys.float_info.min, soft_max=sys.float_info.max, step=3, precision=2, options={'ANIMATABLE'}, subtype='NONE', unit='NONE', update=None)\n"
"\n"
" Returns a new float property definition.\n"
"\n"
BPY_PROPDEF_NAME_DOC
BPY_PROPDEF_DESC_DOC
-" :arg options: Enumerator in ['HIDDEN', 'ANIMATABLE'].\n"
+" :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE'].\n"
" :type options: set\n"
" :arg subtype: Enumerator in ['UNSIGNED', 'PERCENTAGE', 'FACTOR', 'ANGLE', 'TIME', 'DISTANCE', 'NONE'].\n"
" :type subtype: string\n"
" :arg unit: Enumerator in ['NONE', 'LENGTH', 'AREA', 'VOLUME', 'ROTATION', 'TIME', 'VELOCITY', 'ACCELERATION'].\n"
" :type unit: string\n"
+BPY_PROPDEF_UPDATE_DOC
);
static PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw)
{
@@ -470,7 +650,7 @@ static PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw)
BPY_PROPDEF_HEAD(FloatProperty)
if(srna) {
- static const char *kwlist[]= {"attr", "name", "description", "default", "min", "max", "soft_min", "soft_max", "step", "precision", "options", "subtype", "unit", NULL};
+ static const char *kwlist[]= {"attr", "name", "description", "default", "min", "max", "soft_min", "soft_max", "step", "precision", "options", "subtype", "unit", "update", NULL};
const char *id=NULL, *name="", *description="";
int id_len;
float min=-FLT_MAX, max=FLT_MAX, soft_min=-FLT_MAX, soft_max=FLT_MAX, step=3, def=0.0f;
@@ -482,14 +662,16 @@ static PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw)
int subtype= PROP_NONE;
char *pyunit= NULL;
int unit= PROP_UNIT_NONE;
+ PyObject *update_cb= NULL;
if (!PyArg_ParseTupleAndKeywords(args, kw,
- "s#|ssffffffiO!ss:FloatProperty",
+ "s#|ssffffffiO!ssO:FloatProperty",
(char **)kwlist, &id, &id_len,
&name, &description, &def,
&min, &max, &soft_min, &soft_max,
&step, &precision, &PySet_Type,
- &pyopts, &pysubtype, &pyunit))
+ &pyopts, &pysubtype, &pyunit,
+ &update_cb))
{
return NULL;
}
@@ -501,6 +683,10 @@ static PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw)
return NULL;
}
+ if (bpy_prop_callback_check(update_cb, 2) == -1) {
+ return NULL;
+ }
+
prop= RNA_def_property(srna, id, PROP_FLOAT, subtype | unit);
RNA_def_property_float_default(prop, def);
RNA_def_property_range(prop, min, max);
@@ -511,13 +697,14 @@ static PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw)
if(opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
if((opts & PROP_ANIMATABLE)==0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
}
+ bpy_prop_callback_assign(prop, update_cb);
RNA_def_property_duplicate_pointers(srna, prop);
}
Py_RETURN_NONE;
}
PyDoc_STRVAR(BPy_FloatVectorProperty_doc,
-".. function:: FloatVectorProperty(name=\"\", description=\"\", default=(0.0, 0.0, 0.0), min=sys.float_info.min, max=sys.float_info.max, soft_min=sys.float_info.min, soft_max=sys.float_info.max, step=3, precision=2, options={'ANIMATABLE'}, subtype='NONE', size=3)\n"
+".. function:: FloatVectorProperty(name=\"\", description=\"\", default=(0.0, 0.0, 0.0), min=sys.float_info.min, max=sys.float_info.max, soft_min=sys.float_info.min, soft_max=sys.float_info.max, step=3, precision=2, options={'ANIMATABLE'}, subtype='NONE', size=3, update=None)\n"
"\n"
" Returns a new vector float property definition.\n"
"\n"
@@ -525,12 +712,13 @@ BPY_PROPDEF_NAME_DOC
BPY_PROPDEF_DESC_DOC
" :arg default: sequence of floats the length of *size*.\n"
" :type default: sequence\n"
-" :arg options: Enumerator in ['HIDDEN', 'ANIMATABLE'].\n"
+" :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE'].\n"
" :type options: set\n"
" :arg subtype: Enumerator in ['COLOR', 'TRANSLATION', 'DIRECTION', 'VELOCITY', 'ACCELERATION', 'MATRIX', 'EULER', 'QUATERNION', 'AXISANGLE', 'XYZ', 'COLOR_GAMMA', 'LAYER', 'NONE'].\n"
" :type subtype: string\n"
" :arg size: Vector dimensions in [1, and " STRINGIFY(PYRNA_STACK_ARRAY) "].\n"
" :type size: int\n"
+BPY_PROPDEF_UPDATE_DOC
);
static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObject *kw)
{
@@ -539,7 +727,7 @@ static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObjec
BPY_PROPDEF_HEAD(FloatVectorProperty)
if(srna) {
- static const char *kwlist[]= {"attr", "name", "description", "default", "min", "max", "soft_min", "soft_max", "step", "precision", "options", "subtype", "size", NULL};
+ static const char *kwlist[]= {"attr", "name", "description", "default", "min", "max", "soft_min", "soft_max", "step", "precision", "options", "subtype", "size", "update", NULL};
const char *id=NULL, *name="", *description="";
int id_len;
float min=-FLT_MAX, max=FLT_MAX, soft_min=-FLT_MAX, soft_max=FLT_MAX, step=3, def[PYRNA_STACK_ARRAY]={0.0f};
@@ -550,14 +738,16 @@ static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObjec
int opts=0;
char *pysubtype= NULL;
int subtype= PROP_NONE;
+ PyObject *update_cb= NULL;
if (!PyArg_ParseTupleAndKeywords(args, kw,
- "s#|ssOfffffiO!si:FloatVectorProperty",
+ "s#|ssOfffffiO!siO:FloatVectorProperty",
(char **)kwlist, &id, &id_len,
&name, &description, &pydef,
&min, &max, &soft_min, &soft_max,
&step, &precision, &PySet_Type,
- &pyopts, &pysubtype, &size))
+ &pyopts, &pysubtype, &size,
+ &update_cb))
{
return NULL;
}
@@ -572,6 +762,10 @@ static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObjec
if(pydef && PyC_AsArray(def, pydef, size, &PyFloat_Type, "FloatVectorProperty(default=sequence)") < 0)
return NULL;
+ if (bpy_prop_callback_check(update_cb, 2) == -1) {
+ return NULL;
+ }
+
prop= RNA_def_property(srna, id, PROP_FLOAT, subtype);
RNA_def_property_array(prop, size);
if(pydef) RNA_def_property_float_array_default(prop, def);
@@ -583,22 +777,24 @@ static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObjec
if(opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
if((opts & PROP_ANIMATABLE)==0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
}
+ bpy_prop_callback_assign(prop, update_cb);
RNA_def_property_duplicate_pointers(srna, prop);
}
Py_RETURN_NONE;
}
PyDoc_STRVAR(BPy_StringProperty_doc,
-".. function:: StringProperty(name=\"\", description=\"\", default=\"\", maxlen=0, options={'ANIMATABLE'}, subtype='NONE')\n"
+".. function:: StringProperty(name=\"\", description=\"\", default=\"\", maxlen=0, options={'ANIMATABLE'}, subtype='NONE', update=None)\n"
"\n"
" Returns a new string property definition.\n"
"\n"
BPY_PROPDEF_NAME_DOC
BPY_PROPDEF_DESC_DOC
-" :arg options: Enumerator in ['HIDDEN', 'ANIMATABLE'].\n"
+" :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE'].\n"
" :type options: set\n"
" :arg subtype: Enumerator in ['FILE_PATH', 'DIR_PATH', 'FILENAME', 'NONE'].\n"
" :type subtype: string\n"
+BPY_PROPDEF_UPDATE_DOC
);
static PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw)
{
@@ -607,7 +803,7 @@ static PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw
BPY_PROPDEF_HEAD(StringProperty)
if(srna) {
- static const char *kwlist[]= {"attr", "name", "description", "default", "maxlen", "options", "subtype", NULL};
+ static const char *kwlist[]= {"attr", "name", "description", "default", "maxlen", "options", "subtype", "update", NULL};
const char *id=NULL, *name="", *description="", *def="";
int id_len;
int maxlen=0;
@@ -616,18 +812,24 @@ static PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw
int opts=0;
char *pysubtype= NULL;
int subtype= PROP_NONE;
+ PyObject *update_cb= NULL;
if (!PyArg_ParseTupleAndKeywords(args, kw,
- "s#|sssiO!s:StringProperty",
+ "s#|sssiO!sO:StringProperty",
(char **)kwlist, &id, &id_len,
&name, &description, &def,
- &maxlen, &PySet_Type, &pyopts, &pysubtype))
+ &maxlen, &PySet_Type, &pyopts, &pysubtype,
+ &update_cb))
{
return NULL;
}
BPY_PROPDEF_SUBTYPE_CHECK(StringProperty, property_flag_items, property_subtype_string_items)
+ if (bpy_prop_callback_check(update_cb, 2) == -1) {
+ return NULL;
+ }
+
prop= RNA_def_property(srna, id, PROP_STRING, subtype);
if(maxlen != 0) RNA_def_property_string_maxlength(prop, maxlen + 1); /* +1 since it includes null terminator */
if(def) RNA_def_property_string_default(prop, def);
@@ -637,6 +839,7 @@ static PyObject *BPy_StringProperty(PyObject *self, PyObject *args, PyObject *kw
if(opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
if((opts & PROP_ANIMATABLE)==0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
}
+ bpy_prop_callback_assign(prop, update_cb);
RNA_def_property_duplicate_pointers(srna, prop);
}
Py_RETURN_NONE;
@@ -803,23 +1006,7 @@ static EnumPropertyItem *bpy_props_enum_itemf(struct bContext *C, PointerRNA *pt
bpy_context_set(C, &gilstate);
args= PyTuple_New(2);
-
- /* first get self */
- /* operators can store their own instance for later use */
- if(ptr->data) {
- void **instance = RNA_struct_instance(ptr);
-
- if(instance) {
- if(*instance) {
- self= *instance;
- Py_INCREF(self);
- }
- }
- }
- if(self == NULL) {
- self= pyrna_struct_CreatePyObject(ptr);
- }
-
+ self= pyrna_struct_as_instance(ptr);
PyTuple_SET_ITEM(args, 0, self);
/* now get the context */
@@ -857,17 +1044,7 @@ static EnumPropertyItem *bpy_props_enum_itemf(struct bContext *C, PointerRNA *pt
*free= 1;
}
else {
- /* since we return to C code we can't leave the error */
- PyCodeObject *f_code= (PyCodeObject *)PyFunction_GET_CODE(py_func);
- PyErr_Print();
- PyErr_Clear();
-
- /* use py style error */
- fprintf(stderr, "File \"%s\", line %d, in %s\n",
- _PyUnicode_AsString(f_code->co_filename),
- f_code->co_firstlineno,
- _PyUnicode_AsString(((PyFunctionObject *)py_func)->func_name)
- );
+ printf_func_error(py_func);
eitems= DummyRNA_NULL_items;
}
@@ -878,7 +1055,7 @@ static EnumPropertyItem *bpy_props_enum_itemf(struct bContext *C, PointerRNA *pt
}
PyDoc_STRVAR(BPy_EnumProperty_doc,
-".. function:: EnumProperty(items, name=\"\", description=\"\", default=\"\", options={'ANIMATABLE'})\n"
+".. function:: EnumProperty(items, name=\"\", description=\"\", default=\"\", options={'ANIMATABLE'}, update=None)\n"
"\n"
" Returns a new enumerator property definition.\n"
"\n"
@@ -888,7 +1065,7 @@ BPY_PROPDEF_DESC_DOC
" is disabled otherwise a set which may only contain string identifiers\n"
" used in *items*.\n"
" :type default: string or set\n"
-" :arg options: Enumerator in ['HIDDEN', 'ANIMATABLE', 'ENUM_FLAG'].\n"
+" :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE', 'ENUM_FLAG'].\n"
" :type options: set\n"
" :arg items: sequence of enum items formatted:\n"
" [(identifier, name, description), ...] where the identifier is used\n"
@@ -897,6 +1074,7 @@ BPY_PROPDEF_DESC_DOC
" the same format as the static list.\n"
" This function must take 2 arguments (self, context)\n"
" :type items: sequence of string triplets or a function\n"
+BPY_PROPDEF_UPDATE_DOC
);
static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw)
{
@@ -905,7 +1083,7 @@ static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw)
BPY_PROPDEF_HEAD(EnumProperty)
if(srna) {
- static const char *kwlist[]= {"attr", "items", "name", "description", "default", "options", NULL};
+ static const char *kwlist[]= {"attr", "items", "name", "description", "default", "options", "update", NULL};
const char *id=NULL, *name="", *description="";
PyObject *def= NULL;
int id_len;
@@ -916,18 +1094,24 @@ static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw)
PyObject *pyopts= NULL;
int opts=0;
short is_itemf= FALSE;
+ PyObject *update_cb= NULL;
if (!PyArg_ParseTupleAndKeywords(args, kw,
- "s#O|ssOO!:EnumProperty",
+ "s#O|ssOO!O:EnumProperty",
(char **)kwlist, &id, &id_len,
&items, &name, &description,
- &def, &PySet_Type, &pyopts))
+ &def, &PySet_Type, &pyopts,
+ &update_cb))
{
return NULL;
}
BPY_PROPDEF_CHECK(EnumProperty, property_flag_enum_items)
+ if (bpy_prop_callback_check(update_cb, 2) == -1) {
+ return NULL;
+ }
+
/* items can be a list or a callable */
if(PyFunction_Check(items)) { /* dont use PyCallable_Check because we need the function code for errors */
PyCodeObject *f_code= (PyCodeObject *)PyFunction_GET_CODE(items);
@@ -975,6 +1159,7 @@ static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw)
if(opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
if((opts & PROP_ANIMATABLE)==0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
}
+ bpy_prop_callback_assign(prop, update_cb);
RNA_def_property_duplicate_pointers(srna, prop);
if(is_itemf == FALSE) {
@@ -1017,7 +1202,7 @@ static StructRNA *pointer_type_from_py(PyObject *value, const char *error_prefix
}
PyDoc_STRVAR(BPy_PointerProperty_doc,
-".. function:: PointerProperty(type=\"\", description=\"\", options={'ANIMATABLE'})\n"
+".. function:: PointerProperty(type=\"\", description=\"\", options={'ANIMATABLE'}, update=None)\n"
"\n"
" Returns a new pointer property definition.\n"
"\n"
@@ -1025,8 +1210,9 @@ PyDoc_STRVAR(BPy_PointerProperty_doc,
" :type type: class\n"
BPY_PROPDEF_NAME_DOC
BPY_PROPDEF_DESC_DOC
-" :arg options: Enumerator in ['HIDDEN', 'ANIMATABLE'].\n"
+" :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE'].\n"
" :type options: set\n"
+BPY_PROPDEF_UPDATE_DOC
);
static PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *kw)
{
@@ -1035,7 +1221,7 @@ static PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *k
BPY_PROPDEF_HEAD(PointerProperty)
if(srna) {
- static const char *kwlist[]= {"attr", "type", "name", "description", "options", NULL};
+ static const char *kwlist[]= {"attr", "type", "name", "description", "options", "update", NULL};
const char *id=NULL, *name="", *description="";
int id_len;
PropertyRNA *prop;
@@ -1043,12 +1229,14 @@ static PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *k
PyObject *type= Py_None;
PyObject *pyopts= NULL;
int opts=0;
+ PyObject *update_cb= NULL;
if (!PyArg_ParseTupleAndKeywords(args, kw,
- "s#O|ssO!:PointerProperty",
+ "s#O|ssO!O:PointerProperty",
(char **)kwlist, &id, &id_len,
&type, &name, &description,
- &PySet_Type, &pyopts))
+ &PySet_Type, &pyopts,
+ &update_cb))
{
return NULL;
}
@@ -1059,11 +1247,16 @@ static PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *k
if(!ptype)
return NULL;
+ if (bpy_prop_callback_check(update_cb, 2) == -1) {
+ return NULL;
+ }
+
prop= RNA_def_pointer_runtime(srna, id, ptype, name, description);
if(pyopts) {
if(opts & PROP_HIDDEN) RNA_def_property_flag(prop, PROP_HIDDEN);
if((opts & PROP_ANIMATABLE)==0) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
}
+ bpy_prop_callback_assign(prop, update_cb);
RNA_def_property_duplicate_pointers(srna, prop);
}
Py_RETURN_NONE;
@@ -1078,7 +1271,7 @@ PyDoc_STRVAR(BPy_CollectionProperty_doc,
" :type type: class\n"
BPY_PROPDEF_NAME_DOC
BPY_PROPDEF_DESC_DOC
-" :arg options: Enumerator in ['HIDDEN', 'ANIMATABLE'].\n"
+" :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE'].\n"
" :type options: set\n"
);
static PyObject *BPy_CollectionProperty(PyObject *self, PyObject *args, PyObject *kw)
diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c
index 4fe13bc6818..38cc3edd8f6 100644
--- a/source/blender/python/intern/bpy_rna.c
+++ b/source/blender/python/intern/bpy_rna.c
@@ -323,11 +323,20 @@ int pyrna_write_check(void)
{
return !rna_disallow_writes;
}
+
+void pyrna_write_set(int val)
+{
+ rna_disallow_writes= !val;
+}
#else // USE_PEDANTIC_WRITE
int pyrna_write_check(void)
{
return TRUE;
}
+void pyrna_write_set(int UNUSED(val))
+{
+ /* nothing */
+}
#endif // USE_PEDANTIC_WRITE
static Py_ssize_t pyrna_prop_collection_length(BPy_PropertyRNA *self);
diff --git a/source/blender/python/intern/bpy_rna.h b/source/blender/python/intern/bpy_rna.h
index dbb5fc2feb7..5db352af53d 100644
--- a/source/blender/python/intern/bpy_rna.h
+++ b/source/blender/python/intern/bpy_rna.h
@@ -183,6 +183,7 @@ PyObject *pyrna_math_object_from_array(PointerRNA *ptr, PropertyRNA *prop);
int pyrna_array_contains_py(PointerRNA *ptr, PropertyRNA *prop, PyObject *value);
int pyrna_write_check(void);
+void pyrna_write_set(int val);
int pyrna_struct_validity_check(BPy_StructRNA *pysrna);
int pyrna_prop_validity_check(BPy_PropertyRNA *self);
diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h
index 47230ab3089..23f301249ba 100644
--- a/source/blender/render/extern/include/RE_pipeline.h
+++ b/source/blender/render/extern/include/RE_pipeline.h
@@ -146,7 +146,7 @@ typedef struct RenderResult {
typedef struct RenderStats {
int cfra;
int totface, totvert, totstrand, tothalo, totlamp, totpart;
- short curfield, curblur, curpart, partsdone, convertdone;
+ short curfield, curblur, curpart, partsdone, convertdone, curfsa;
double starttime, lastframetime;
const char *infostr, *statstr;
char scenename[32];
diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h
index cf16211b6d1..b2535ebc9ea 100644
--- a/source/blender/render/intern/include/render_types.h
+++ b/source/blender/render/intern/include/render_types.h
@@ -214,7 +214,7 @@ struct Render
ListBase instancetable;
int totinstance;
- struct Image *backbuf, *bakebuf;
+ struct Image *bakebuf;
struct GHash *orco_hash;
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
index c1c2fb60abd..15fc9d38c01 100644
--- a/source/blender/render/intern/source/convertblender.c
+++ b/source/blender/render/intern/source/convertblender.c
@@ -4665,7 +4665,6 @@ void RE_Database_Free(Render *re)
re->totvlak=re->totvert=re->totstrand=re->totlamp=re->tothalo= 0;
re->i.convertdone= 0;
- re->backbuf= NULL;
re->bakebuf= NULL;
if(re->scene)
diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c
index 1e40ab886ae..e2ab21ef877 100644
--- a/source/blender/render/intern/source/envmap.c
+++ b/source/blender/render/intern/source/envmap.c
@@ -149,7 +149,6 @@ static Render *envmap_render_copy(Render *re, EnvMap *env)
envre->r.layers.first= envre->r.layers.last= NULL;
envre->r.filtertype= 0;
envre->r.xparts= envre->r.yparts= 2;
- envre->r.bufflag= 0;
envre->r.size= 100;
envre->r.yasp= envre->r.xasp= 1;
diff --git a/source/blender/render/intern/source/imagetexture.c b/source/blender/render/intern/source/imagetexture.c
index 7d2c7b35247..cb08ae96bf7 100644
--- a/source/blender/render/intern/source/imagetexture.c
+++ b/source/blender/render/intern/source/imagetexture.c
@@ -76,6 +76,8 @@
extern struct Render R;
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+static void boxsample(ImBuf *ibuf, float minx, float miny, float maxx, float maxy, TexResult *texres, int imaprepeat, int imapextend);
+
/* *********** IMAGEWRAPPING ****************** */
@@ -201,7 +203,16 @@ int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, float *texvec, TexResult *texre
ibuf->rect+= (ibuf->x*ibuf->y);
}
- ibuf_get_color(&texres->tr, ibuf, x, y);
+ /* interpolate */
+ if (tex->imaflag & TEX_INTERPOL) {
+ float filterx, filtery;
+ filterx = (0.5f * tex->filtersize) / ibuf->x;
+ filtery = (0.5f * tex->filtersize) / ibuf->y;
+
+ boxsample(ibuf, fx-filterx, fy-filtery, fx+filterx, fy+filtery, texres, (tex->extend==TEX_REPEAT), (tex->extend==TEX_EXTEND));
+ }
+ else /* no filtering */
+ ibuf_get_color(&texres->tr, ibuf, x, y);
if( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) ) {
ibuf->rect-= (ibuf->x*ibuf->y);
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index 436f0ecd997..90f07586786 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -2065,36 +2065,6 @@ static void do_render_fields_3d(Render *re)
re->display_draw(re->ddh, re->result, NULL);
}
-static void load_backbuffer(Render *re)
-{
- if(re->r.alphamode == R_ADDSKY) {
- ImBuf *ibuf;
- char name[256];
-
- BLI_strncpy(name, re->r.backbuf, sizeof(name));
- BLI_path_abs(name, re->main->name);
- BLI_path_frame(name, re->r.cfra, 0);
-
- if(re->backbuf) {
- re->backbuf->id.us--;
- if(re->backbuf->id.us<1)
- BKE_image_signal(re->backbuf, NULL, IMA_SIGNAL_RELOAD);
- }
-
- re->backbuf= BKE_add_image_file(name);
- ibuf= BKE_image_get_ibuf(re->backbuf, NULL);
- if(ibuf==NULL) {
- // error() doesnt work with render window open
- //error("No backbuf there!");
- printf("Error: No backbuf %s\n", name);
- }
- else {
- if (re->r.mode & R_FIELDS)
- image_de_interlace(re->backbuf, re->r.mode & R_ODDFIELD);
- }
- }
-}
-
/* main render routine, no compositing */
static void do_render_fields_blur_3d(Render *re)
{
@@ -2105,10 +2075,6 @@ static void do_render_fields_blur_3d(Render *re)
G.afbreek= 1;
return;
}
-
- /* backbuffer initialize */
- if(re->r.bufflag & 1)
- load_backbuffer(re);
/* now use renderdata and camera to set viewplane */
RE_SetCamera(re, camera);
@@ -2203,6 +2169,24 @@ static void render_scene(Render *re, Scene *sce, int cfra)
do_render_fields_blur_3d(resc);
}
+/* helper call to detect if this scene needs a render, or if there's a any render layer to render */
+static int composite_needs_render(Scene *sce, int this_scene)
+{
+ bNodeTree *ntree= sce->nodetree;
+ bNode *node;
+
+ if(ntree==NULL) return 1;
+ if(sce->use_nodes==0) return 1;
+ if((sce->r.scemode & R_DOCOMP)==0) return 1;
+
+ for(node= ntree->nodes.first; node; node= node->next) {
+ if(node->type==CMP_NODE_R_LAYERS)
+ if(this_scene==0 || node->id==NULL || node->id==&sce->id)
+ return 1;
+ }
+ return 0;
+}
+
static void tag_scenes_for_render(Render *re)
{
bNode *node;
@@ -2211,7 +2195,8 @@ static void tag_scenes_for_render(Render *re)
for(sce= re->main->scene.first; sce; sce= sce->id.next)
sce->id.flag &= ~LIB_DOIT;
- re->scene->id.flag |= LIB_DOIT;
+ if(RE_GetCamera(re) && composite_needs_render(re->scene, 1))
+ re->scene->id.flag |= LIB_DOIT;
if(re->scene->nodetree==NULL) return;
@@ -2258,24 +2243,6 @@ static void ntree_render_scenes(Render *re)
set_scene_bg(re->main, re->scene);
}
-/* helper call to detect if theres a composite with render-result node */
-static int composite_needs_render(Scene *sce)
-{
- bNodeTree *ntree= sce->nodetree;
- bNode *node;
-
- if(ntree==NULL) return 1;
- if(sce->use_nodes==0) return 1;
- if((sce->r.scemode & R_DOCOMP)==0) return 1;
-
- for(node= ntree->nodes.first; node; node= node->next) {
- if(node->type==CMP_NODE_R_LAYERS)
- if(node->id==NULL || node->id==&sce->id)
- return 1;
- }
- return 0;
-}
-
/* bad call... need to think over proper method still */
static void render_composit_stats(void *UNUSED(arg), char *str)
{
@@ -2291,6 +2258,16 @@ static void do_merge_fullsample(Render *re, bNodeTree *ntree)
float *rectf, filt[3][3];
int sample;
+ /* interaction callbacks */
+ if(ntree) {
+ ntree->stats_draw= render_composit_stats;
+ ntree->test_break= re->test_break;
+ ntree->progress= re->progress;
+ ntree->sdh= re->sdh;
+ ntree->tbh= re->tbh;
+ ntree->prh= re->prh;
+ }
+
/* filtmask needs it */
R= *re;
@@ -2298,25 +2275,27 @@ static void do_merge_fullsample(Render *re, bNodeTree *ntree)
rectf= MEM_mapallocN(re->rectx*re->recty*sizeof(float)*4, "fullsample rgba");
for(sample=0; sample<re->r.osa; sample++) {
+ Render *re1;
RenderResult rres;
int x, y, mask;
- /* set all involved renders on the samplebuffers (first was done by render itself) */
+ /* enable full sample print */
+ R.i.curfsa= sample+1;
+
+ /* set all involved renders on the samplebuffers (first was done by render itself, but needs tagged) */
/* also function below assumes this */
- if(sample) {
- Render *re1;
- tag_scenes_for_render(re);
- for(re1= RenderGlobal.renderlist.first; re1; re1= re1->next) {
- if(re1->scene->id.flag & LIB_DOIT) {
- if(re1->r.scemode & R_FULL_SAMPLE) {
+ tag_scenes_for_render(re);
+ for(re1= RenderGlobal.renderlist.first; re1; re1= re1->next) {
+ if(re1->scene->id.flag & LIB_DOIT) {
+ if(re1->r.scemode & R_FULL_SAMPLE) {
+ if(sample)
read_render_result(re1, sample);
- ntreeCompositTagRender(re1->scene); /* ensure node gets exec to put buffers on stack */
- }
+ ntreeCompositTagRender(re1->scene); /* ensure node gets exec to put buffers on stack */
}
}
}
-
+
/* composite */
if(ntree) {
ntreeCompositTagRender(re->scene);
@@ -2359,6 +2338,17 @@ static void do_merge_fullsample(Render *re, bNodeTree *ntree)
break;
}
+ /* clear interaction callbacks */
+ if(ntree) {
+ ntree->stats_draw= NULL;
+ ntree->test_break= NULL;
+ ntree->progress= NULL;
+ ntree->tbh= ntree->sdh= ntree->prh= NULL;
+ }
+
+ /* disable full sample print */
+ R.i.curfsa= 0;
+
BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
if(re->result->rectf)
MEM_freeN(re->result->rectf);
@@ -2398,8 +2388,10 @@ void RE_MergeFullSample(Render *re, Main *bmain, Scene *sce, bNodeTree *ntree)
}
/* own render result should be read/allocated */
- if(re->scene->id.flag & LIB_DOIT)
+ if(re->scene->id.flag & LIB_DOIT) {
RE_ReadRenderResult(re->scene, re->scene);
+ re->scene->id.flag &= ~LIB_DOIT;
+ }
/* and now we can draw (result is there) */
re->display_init(re->dih, re->result);
@@ -2417,12 +2409,21 @@ static void do_render_composite_fields_blur_3d(Render *re)
/* INIT seeding, compositor can use random texture */
BLI_srandom(re->r.cfra);
- if(composite_needs_render(re->scene)) {
+ if(composite_needs_render(re->scene, 1)) {
/* save memory... free all cached images */
ntreeFreeCache(ntree);
do_render_fields_blur_3d(re);
- } else {
+ }
+ else {
+ /* 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);
+
+ BLI_rw_mutex_unlock(&re->resultmutex);
+
/* scene render process already updates animsys */
update_newframe = 1;
}
@@ -2758,7 +2759,7 @@ int RE_is_rendering_allowed(Scene *scene, Object *camera_override, void *erh, vo
}
if(scene->r.scemode & R_FULL_SAMPLE) {
- if(composite_needs_render(scene)==0) {
+ if(composite_needs_render(scene, 0)==0) {
error(erh, "Full Sample AA not supported without 3d rendering");
return 0;
}
diff --git a/source/blender/render/intern/source/pixelshading.c b/source/blender/render/intern/source/pixelshading.c
index 2d42938f6ac..56a1c870904 100644
--- a/source/blender/render/intern/source/pixelshading.c
+++ b/source/blender/render/intern/source/pixelshading.c
@@ -502,21 +502,6 @@ int shadeHaloFloat(HaloRen *har, float *col, int zz,
/* ------------------------------------------------------------------------- */
-static void fillBackgroundImage(float *collector, float fx, float fy)
-{
- collector[0] = 0.0;
- collector[1] = 0.0;
- collector[2] = 0.0;
- collector[3] = 0.0;
-
- if(R.backbuf) {
- float dx= 1.0f/(float)R.winx;
- float dy= 1.0f/(float)R.winy;
-
- image_sample(R.backbuf, fx*dx, fy*dy, dx, dy, collector);
- }
-}
-
/* Only view vector is important here. Result goes to colf[3] */
void shadeSkyView(float *colf, float *rco, float *view, float *dxyview, short thread)
{
@@ -626,18 +611,14 @@ void shadeSkyPixel(float *collector, float fx, float fy, short thread)
float fac;
- /* 1. Do a backbuffer image: */
- if(R.r.bufflag & 1) {
- fillBackgroundImage(collector, fx, fy);
- }
- else if((R.wrld.skytype & (WO_SKYBLEND+WO_SKYTEX))==0) {
- /* 2. solid color */
+ if((R.wrld.skytype & (WO_SKYBLEND+WO_SKYTEX))==0) {
+ /* 1. solid color */
VECCOPY(collector, &R.wrld.horr);
collector[3] = 0.0f;
}
else {
- /* 3. */
+ /* 2. */
/* This one true because of the context of this routine */
if(R.wrld.skytype & WO_SKYPAPER) {
diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c
index 5f5dab94ba3..c4587b83fcd 100644
--- a/source/blender/render/intern/source/render_texture.c
+++ b/source/blender/render/intern/source/render_texture.c
@@ -2192,6 +2192,7 @@ void do_material_tex(ShadeInput *shi)
}
}
else if(mtex->texco==TEXCO_REFL) {
+ calc_R_ref(shi);
co= shi->ref; dx= shi->dxref; dy= shi->dyref;
}
else if(mtex->texco==TEXCO_NORM) {
@@ -2509,9 +2510,6 @@ void do_material_tex(ShadeInput *shi)
shi->orn[0]= -shi->vn[0];
shi->orn[1]= -shi->vn[1];
shi->orn[2]= -shi->vn[2];
-
- /* reflection vector */
- calc_R_ref(shi);
}
}
diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c
index bc6c4795f5c..0087be8cca9 100644
--- a/source/blender/render/intern/source/rendercore.c
+++ b/source/blender/render/intern/source/rendercore.c
@@ -2018,74 +2018,6 @@ typedef struct BakeShade {
short *do_update;
} BakeShade;
-/* bake uses a char mask to know what has been baked */
-#define BAKE_MASK_NULL 0
-#define BAKE_MASK_MARGIN 1
-#define BAKE_MASK_BAKED 2
-static void bake_mask_filter_extend( char *mask, int width, int height )
-{
- char *row1, *row2, *row3;
- int rowlen, x, y;
- char *temprect;
-
- rowlen= width;
-
- /* make a copy, to prevent flooding */
- temprect= MEM_dupallocN(mask);
-
- for(y=1; y<=height; y++) {
- /* setup rows */
- row1= (char *)(temprect + (y-2)*rowlen);
- row2= row1 + rowlen;
- row3= row2 + rowlen;
- if(y==1)
- row1= row2;
- else if(y==height)
- row3= row2;
-
- for(x=0; x<rowlen; x++) {
- if (mask[((y-1)*rowlen)+x]==0) {
- if (*row1 || *row2 || *row3 || *(row1+1) || *(row3+1) ) {
- mask[((y-1)*rowlen)+x] = BAKE_MASK_MARGIN;
- } else if((x!=rowlen-1) && (*(row1+2) || *(row2+2) || *(row3+2)) ) {
- mask[((y-1)*rowlen)+x] = BAKE_MASK_MARGIN;
- }
- }
-
- if(x!=0) {
- row1++; row2++; row3++;
- }
- }
- }
- MEM_freeN(temprect);
-}
-
-static void bake_mask_clear( ImBuf *ibuf, char *mask, char val )
-{
- int x,y;
- if (ibuf->rect_float) {
- for(x=0; x<ibuf->x; x++) {
- for(y=0; y<ibuf->y; y++) {
- if (mask[ibuf->x*y + x] == val) {
- float *col= ibuf->rect_float + 4*(ibuf->x*y + x);
- col[0] = col[1] = col[2] = col[3] = 0.0f;
- }
- }
- }
-
- } else {
- /* char buffer */
- for(x=0; x<ibuf->x; x++) {
- for(y=0; y<ibuf->y; y++) {
- if (mask[ibuf->x*y + x] == val) {
- char *col= (char *)(ibuf->rect + ibuf->x*y + x);
- col[0] = col[1] = col[2] = col[3] = 0;
- }
- }
- }
- }
-}
-
static void bake_set_shade_input(ObjectInstanceRen *obi, VlakRen *vlr, ShadeInput *shi, int quad, int isect, int x, int y, float u, float v)
{
if(quad)
@@ -2281,7 +2213,7 @@ static void bake_shade(void *handle, Object *ob, ShadeInput *shi, int quad, int
}
if (bs->rect_mask) {
- bs->rect_mask[bs->rectx*y + x] = BAKE_MASK_BAKED;
+ bs->rect_mask[bs->rectx*y + x] = FILTER_MASK_USED;
}
}
@@ -2308,7 +2240,7 @@ static void bake_displacement(void *handle, ShadeInput *shi, float dist, int x,
col[3]= 255;
}
if (bs->rect_mask) {
- bs->rect_mask[bs->rectx*y + x] = BAKE_MASK_BAKED;
+ bs->rect_mask[bs->rectx*y + x] = FILTER_MASK_USED;
}
}
@@ -2750,16 +2682,16 @@ int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_up
char *temprect;
for(a=0; a<re->r.bake_filter; a++)
- bake_mask_filter_extend((char *)ibuf->userdata, ibuf->x, ibuf->y);
+ IMB_mask_filter_extend((char *)ibuf->userdata, ibuf->x, ibuf->y);
temprect = MEM_dupallocN(ibuf->userdata);
/* expand twice to clear this many pixels, so they blend back in */
- bake_mask_filter_extend(temprect, ibuf->x, ibuf->y);
- bake_mask_filter_extend(temprect, ibuf->x, ibuf->y);
+ IMB_mask_filter_extend(temprect, ibuf->x, ibuf->y);
+ IMB_mask_filter_extend(temprect, ibuf->x, ibuf->y);
/* clear all pixels in the margin*/
- bake_mask_clear(ibuf, temprect, BAKE_MASK_MARGIN);
+ IMB_mask_clear(ibuf, temprect, FILTER_MASK_MARGIN);
MEM_freeN(temprect);
}
diff --git a/source/blender/render/intern/source/shadeinput.c b/source/blender/render/intern/source/shadeinput.c
index 77141d9b445..e22ddd28dda 100644
--- a/source/blender/render/intern/source/shadeinput.c
+++ b/source/blender/render/intern/source/shadeinput.c
@@ -543,11 +543,6 @@ void shade_input_set_strand_texco(ShadeInput *shi, StrandRen *strand, StrandVert
shi->orn[2]= -shi->vn[2];
}
- if(texco & TEXCO_REFL) {
- /* mirror reflection color textures (and envmap) */
- calc_R_ref(shi); /* wrong location for normal maps! XXXXXXXXXXXXXX */
- }
-
if(texco & TEXCO_STRESS) {
/* not supported */
}
@@ -1205,11 +1200,6 @@ void shade_input_set_shade_texco(ShadeInput *shi)
shi->orn[2]= -shi->vn[2];
}
- if(texco & TEXCO_REFL) {
- /* mirror reflection color textures (and envmap) */
- calc_R_ref(shi); /* wrong location for normal maps! XXXXXXXXXXXXXX */
- }
-
if(texco & TEXCO_STRESS) {
float *s1, *s2, *s3;
diff --git a/source/blender/render/intern/source/sunsky.c b/source/blender/render/intern/source/sunsky.c
index f645c29a7a5..5877fa42292 100644
--- a/source/blender/render/intern/source/sunsky.c
+++ b/source/blender/render/intern/source/sunsky.c
@@ -460,7 +460,7 @@ void AtmospherePixleShader( struct SunSky* sunSky, float view[3], float s, float
vec3opv(sunSky->atm_BetaRM, sunSky->atm_BetaRay, +, sunSky->atm_BetaMie);
//e^(-(beta_1 + beta_2) * s) = E1
- vec3opf(E1, sunSky->atm_BetaRM, *, -s/log(2));
+ vec3opf(E1, sunSky->atm_BetaRM, *, -s/M_LN2);
E1[0] = exp(E1[0]);
E1[1] = exp(E1[1]);
E1[2] = exp(E1[2]);
diff --git a/source/blender/render/intern/source/volumetric.c b/source/blender/render/intern/source/volumetric.c
index 09422af7c79..c4e741b6c61 100644
--- a/source/blender/render/intern/source/volumetric.c
+++ b/source/blender/render/intern/source/volumetric.c
@@ -605,7 +605,7 @@ static void volumeintegrate(struct ShadeInput *shi, float *col, float *co, float
for (; t0 < t1; pt0 = t0, t0 += stepsize) {
const float density = vol_get_density(shi, p);
- if (density > 0.01f) {
+ if (density > 0.00001f) {
float scatter_col[3] = {0.f, 0.f, 0.f}, emit_col[3];
const float stepd = (t0 - pt0) * density;
diff --git a/source/blender/windowmanager/CMakeLists.txt b/source/blender/windowmanager/CMakeLists.txt
index 76ba298cd5f..0cf59a9b598 100644
--- a/source/blender/windowmanager/CMakeLists.txt
+++ b/source/blender/windowmanager/CMakeLists.txt
@@ -101,7 +101,6 @@ endif()
if(WITH_PYTHON)
list(APPEND INC ../python)
- list(APPEND INC_SYS ${PYTHON_INCLUDE_DIRS})
add_definitions(-DWITH_PYTHON)
if(WITH_PYTHON_SECURITY)
@@ -115,7 +114,9 @@ endif()
if(APPLE)
if(NOT WITH_COCOA)
- list(APPEND SRC intern/wm_apple.c)
+ list(APPEND SRC
+ intern/wm_apple.c
+ )
endif()
endif()
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index 3f9a3f636d0..67294a8eb53 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -278,14 +278,19 @@ void WM_menutype_free(void);
/* default operator callbacks for border/circle/lasso */
int WM_border_select_invoke (struct bContext *C, struct wmOperator *op, struct wmEvent *event);
int WM_border_select_modal (struct bContext *C, struct wmOperator *op, struct wmEvent *event);
+int WM_border_select_cancel(struct bContext *C, struct wmOperator *op);
int WM_gesture_circle_invoke(struct bContext *C, struct wmOperator *op, struct wmEvent *event);
int WM_gesture_circle_modal(struct bContext *C, struct wmOperator *op, struct wmEvent *event);
+int WM_gesture_circle_cancel(struct bContext *C, struct wmOperator *op);
int WM_gesture_lines_invoke(struct bContext *C, struct wmOperator *op, struct wmEvent *event);
int WM_gesture_lines_modal(struct bContext *C, struct wmOperator *op, struct wmEvent *event);
+int WM_gesture_lines_cancel(struct bContext *C, struct wmOperator *op);
int WM_gesture_lasso_invoke(struct bContext *C, struct wmOperator *op, struct wmEvent *event);
int WM_gesture_lasso_modal(struct bContext *C, struct wmOperator *op, struct wmEvent *event);
+int WM_gesture_lasso_cancel(struct bContext *C, struct wmOperator *op);
int WM_gesture_straightline_invoke(struct bContext *C, struct wmOperator *op, struct wmEvent *event);
int WM_gesture_straightline_modal(struct bContext *C, struct wmOperator *op, struct wmEvent *event);
+int WM_gesture_straightline_cancel(struct bContext *C, struct wmOperator *op);
/* default operator for arearegions, generates event */
void WM_OT_tweak_gesture(struct wmOperatorType *ot);
diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h
index ab68c6ef4d4..49bd3ede37d 100644
--- a/source/blender/windowmanager/WM_types.h
+++ b/source/blender/windowmanager/WM_types.h
@@ -61,6 +61,10 @@ struct ImBuf;
#define OPTYPE_MACRO 8
#define OPTYPE_GRAB_POINTER 16 /* */
#define OPTYPE_PRESET 32 /* show preset menu */
+#define OPTYPE_INTERNAL 64 /* some operators are mainly for internal use
+ * and don't make sense to be accessed from the
+ * search menu, even if poll() returns TRUE.
+ * currently only used for the search toolbox */
/* context to call operator in for WM_operator_name_call */
/* rna_ui.c contains EnumPropertyItem's of these, keep in sync */
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index 615259bda15..2613cb8f14f 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -340,7 +340,7 @@ static int wm_handler_ui_call(bContext *C, wmEventHandler *handler, wmEvent *eve
int is_wheel= ELEM(event->type, WHEELUPMOUSE, WHEELDOWNMOUSE);
int retval;
- /* UI is quite agressive with swallowing events, like scrollwheel */
+ /* UI is quite aggressive with swallowing events, like scrollwheel */
/* I realize this is not extremely nice code... when UI gets keymaps it can be maybe smarter */
if(do_wheel_ui==0) {
if(is_wheel)
@@ -1289,16 +1289,23 @@ static int wm_handler_fileselect_call(bContext *C, ListBase *handlers, wmEventHa
if (handler->op_area == NULL) {
bScreen *screen = CTX_wm_screen(C);
sa = (ScrArea *)screen->areabase.first;
- } else
+ }
+ else {
sa = handler->op_area;
+ }
- if(event->val==EVT_FILESELECT_OPEN)
- ED_area_newspace(C, sa, SPACE_FILE);
- else
- ED_screen_full_newspace(C, sa, SPACE_FILE); /* sets context */
-
+ if(event->val==EVT_FILESELECT_OPEN) {
+ ED_area_newspace(C, sa, SPACE_FILE); /* 'sa' is modified in-place */
+ }
+ else {
+ sa= ED_screen_full_newspace(C, sa, SPACE_FILE); /* sets context */
+ }
+
+ /* note, getting the 'sa' back from the context causes a nasty bug where the newly created
+ * 'sa' != CTX_wm_area(C). removed the line below and set 'sa' in the 'if' above */
+ /* sa = CTX_wm_area(C); */
+
/* settings for filebrowser, sfile is not operator owner but sends events */
- sa = CTX_wm_area(C);
sfile= (SpaceFile*)sa->spacedata.first;
sfile->op= handler->op;
@@ -1570,7 +1577,7 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers)
* so check for mouse moves too.
* note2: the first click event will be handled but still used to create a
* double click event if clicking again quickly.
- * If no double click events are found itwill fallback to a single click.
+ * If no double click events are found it will fallback to a single click.
* So a double click event can result in 2 successive single click calls
* if its not handled by the keymap - campbell */
if ( (ABS(event->x - win->eventstate->prevclickx)) <= 2 &&
diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c
index 313e9357094..79ec0360ac6 100644
--- a/source/blender/windowmanager/intern/wm_files.c
+++ b/source/blender/windowmanager/intern/wm_files.c
@@ -490,15 +490,16 @@ int WM_read_homefile(bContext *C, ReportList *reports, short from_memory)
/* prevent buggy files that had G_FILE_RELATIVE_REMAP written out by mistake. Screws up autosaves otherwise
* can remove this eventually, only in a 2.53 and older, now its not written */
G.fileflags &= ~G_FILE_RELATIVE_REMAP;
-
+
+ /* check userdef before open window, keymaps etc */
+ wm_init_userdef(C);
+
/* match the read WM with current WM */
wm_window_match_do(C, &wmbase);
WM_check(C); /* opens window(s), checks keymaps */
G.main->name[0]= '\0';
- wm_init_userdef(C);
-
/* When loading factory settings, the reset solid OpenGL lights need to be applied. */
if (!G.background) GPU_default_lights();
@@ -751,7 +752,10 @@ int WM_write_file(bContext *C, const char *target, int fileflags, ReportList *re
if(fileflags & G_FILE_AUTOPLAY) G.fileflags |= G_FILE_AUTOPLAY;
else G.fileflags &= ~G_FILE_AUTOPLAY;
- write_history();
+ /* prevent background mode scripts from clobbering history */
+ if(!G.background) {
+ write_history();
+ }
/* run this function after because the file cant be written before the blend is */
if (ibuf_thumb) {
diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c
index 2e4148ca51d..d57c94a5826 100644
--- a/source/blender/windowmanager/intern/wm_init_exit.c
+++ b/source/blender/windowmanager/intern/wm_init_exit.c
@@ -328,7 +328,6 @@ static void free_openrecent(void)
/* bad stuff*/
-extern ListBase editelems;
extern wchar_t *copybuf;
extern wchar_t *copybufinfo;
@@ -394,10 +393,6 @@ void WM_exit(bContext *C)
free_anim_drivers_copybuf();
free_fmodifiers_copybuf();
free_posebuf();
-// free_vertexpaint();
-// free_imagepaint();
-
-// fsmenu_free();
BLF_exit();
@@ -420,10 +415,6 @@ void WM_exit(bContext *C)
BPY_python_end();
#endif
- if (!G.background) {
-// XXX UI_filelist_free_icons();
- }
-
GPU_buffer_pool_free(NULL);
GPU_free_unused_buffers();
GPU_extensions_exit();
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index 34702558bc8..06d049d2cb5 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -727,14 +727,14 @@ static uiBlock *wm_enum_search_menu(bContext *C, ARegion *ar, void *arg_op)
block= uiBeginBlock(C, ar, "_popup", UI_EMBOSS);
uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_RET_1|UI_BLOCK_MOVEMOUSE_QUIT);
- //uiDefBut(block, LABEL, 0, op->type->name, 10, 10, 180, 19, NULL, 0.0, 0.0, 0, 0, ""); // ok, this isnt so easy...
- but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, 256, 10, 10, 180, 19, 0, 0, "");
+ //uiDefBut(block, LABEL, 0, op->type->name, 10, 10, 180, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); // ok, this isnt so easy...
+ but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, 256, 10, 10, 9*UI_UNIT_X, UI_UNIT_Y, 0, 0, "");
uiButSetSearchFunc(but, operator_enum_search_cb, op->type, operator_enum_call_cb, NULL);
/* fake button, it holds space for search items */
- uiDefBut(block, LABEL, 0, "", 10, 10 - uiSearchBoxhHeight(), 180, uiSearchBoxhHeight(), NULL, 0, 0, 0, 0, NULL);
+ uiDefBut(block, LABEL, 0, "", 10, 10 - uiSearchBoxhHeight(), 9*UI_UNIT_X, uiSearchBoxhHeight(), NULL, 0, 0, 0, 0, NULL);
- uiPopupBoundsBlock(block, 6, 0, -20); /* move it downwards, mouse over button */
+ uiPopupBoundsBlock(block, 6, 0, -UI_UNIT_Y); /* move it downwards, mouse over button */
uiEndBlock(C, block);
event= *(win->eventstate); /* XXX huh huh? make api call */
@@ -916,12 +916,21 @@ static uiBlock *wm_block_create_redo(bContext *C, ARegion *ar, void *arg_op)
assert(op->type->flag & OPTYPE_REGISTER);
uiBlockSetHandleFunc(block, ED_undo_operator_repeat_cb_evt, arg_op);
- layout= uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, width, 20, style);
+ layout= uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, width, UI_UNIT_Y, style);
if(ED_undo_valid(C, op->type->name)==0)
uiLayoutSetEnabled(layout, 0);
- uiLayoutOperatorButs(C, layout, op, NULL, 'H', UI_LAYOUT_OP_SHOW_TITLE);
+ if(op->type->flag & OPTYPE_MACRO) {
+ for(op= op->macro.first; op; op= op->next) {
+ uiItemL(layout, op->type->name, ICON_NONE);
+ uiLayoutOperatorButs(C, layout, op, NULL, 'H', UI_LAYOUT_OP_SHOW_TITLE);
+ }
+ }
+ else {
+ uiLayoutOperatorButs(C, layout, op, NULL, 'H', UI_LAYOUT_OP_SHOW_TITLE);
+ }
+
uiPopupBoundsBlock(block, 4, 0, 0);
uiEndBlock(C, block);
@@ -981,7 +990,7 @@ static uiBlock *wm_block_create_dialog(bContext *C, ARegion *ar, void *userData)
col= uiLayoutColumn(layout, FALSE);
col_block= uiLayoutGetBlock(col);
/* Create OK button, the callback of which will execute op */
- btn= uiDefBut(col_block, BUT, 0, "OK", 0, -30, 0, 20, NULL, 0, 0, 0, 0, "");
+ btn= uiDefBut(col_block, BUT, 0, "OK", 0, -30, 0, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
uiButSetFunc(btn, dialog_exec_cb, op, col_block);
}
@@ -1087,7 +1096,7 @@ static int wm_debug_menu_exec(bContext *C, wmOperator *op)
static int wm_debug_menu_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
{
RNA_int_set(op->ptr, "debug_value", G.rt);
- return WM_operator_props_dialog_popup(C, op, 180, 20);
+ return WM_operator_props_dialog_popup(C, op, 9*UI_UNIT_X, UI_UNIT_Y);
}
static void WM_OT_debug_menu(wmOperatorType *ot)
@@ -1185,8 +1194,8 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar
uiBlockSetFunc(block, wm_block_splash_refreshmenu, block, NULL);
#ifdef NAN_BUILDINFO
- uiDefBut(block, LABEL, 0, version_str, 494-ver_width, 282-24, ver_width, 20, NULL, 0, 0, 0, 0, NULL);
- uiDefBut(block, LABEL, 0, revision_str, 494-rev_width, 282-36, rev_width, 20, NULL, 0, 0, 0, 0, NULL);
+ uiDefBut(block, LABEL, 0, version_str, 494-ver_width, 282-24, ver_width, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
+ uiDefBut(block, LABEL, 0, revision_str, 494-rev_width, 282-36, rev_width, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
#endif //NAN_BUILDINFO
layout= uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 10, 2, 480, 110, style);
@@ -1277,7 +1286,10 @@ static void operator_search_cb(const struct bContext *C, void *UNUSED(arg), cons
wmOperatorType *ot = WM_operatortype_first();
for(; ot; ot= ot->next) {
-
+
+ if((ot->flag & OPTYPE_INTERNAL) && (G.f & G_DEBUG) == 0)
+ continue;
+
if(BLI_strcasestr(ot->name, str)) {
if(WM_operator_poll((bContext*)C, ot)) {
char name[256];
@@ -1310,13 +1322,13 @@ static uiBlock *wm_block_search_menu(bContext *C, ARegion *ar, void *UNUSED(arg_
block= uiBeginBlock(C, ar, "_popup", UI_EMBOSS);
uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_RET_1|UI_BLOCK_MOVEMOUSE_QUIT);
- but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, 256, 10, 10, 180, 19, 0, 0, "");
+ but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, 256, 10, 10, 9*UI_UNIT_X, UI_UNIT_Y, 0, 0, "");
uiButSetSearchFunc(but, operator_search_cb, NULL, operator_call_cb, NULL);
/* fake button, it holds space for search items */
- uiDefBut(block, LABEL, 0, "", 10, 10 - uiSearchBoxhHeight(), 180, uiSearchBoxhHeight(), NULL, 0, 0, 0, 0, NULL);
+ uiDefBut(block, LABEL, 0, "", 10, 10 - uiSearchBoxhHeight(), 9*UI_UNIT_X, uiSearchBoxhHeight(), NULL, 0, 0, 0, 0, NULL);
- uiPopupBoundsBlock(block, 6, 0, -20); /* move it downwards, mouse over button */
+ uiPopupBoundsBlock(block, 6, 0, -UI_UNIT_Y); /* move it downwards, mouse over button */
uiEndBlock(C, block);
event= *(win->eventstate); /* XXX huh huh? make api call */
@@ -1389,6 +1401,8 @@ static void WM_OT_call_menu(wmOperatorType *ot)
ot->exec= wm_call_menu_exec;
ot->poll= WM_operator_winactive;
+ ot->flag= OPTYPE_INTERNAL;
+
RNA_def_string(ot->srna, "name", "", BKE_ST_MAXNAME, "Name", "Name of the menu");
}
@@ -1471,6 +1485,14 @@ static int wm_open_mainfile_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(
{
const char *openname= G.main->name;
+ if(CTX_wm_window(C) == NULL) {
+ /* in rare cases this could happen, when trying to invoke in background
+ * mode on load for example. Don't use poll for this because exec()
+ * can still run without a window */
+ BKE_report(op->reports, RPT_ERROR, "Context window not set");
+ return OPERATOR_CANCELLED;
+ }
+
/* if possible, get the name of the most recently used .blend file */
if (G.recent_files.first) {
struct RecentFile *recent = G.recent_files.first;
@@ -1521,7 +1543,7 @@ static void WM_OT_open_mainfile(wmOperatorType *ot)
ot->invoke= wm_open_mainfile_invoke;
ot->exec= wm_open_mainfile_exec;
- ot->poll= WM_operator_winactive;
+ /* ommit window poll so this can work in background mode */
WM_operator_properties_filesel(ot, FOLDERFILE|BLENDERFILE, FILE_BLENDER, FILE_OPENFILE, WM_FILESEL_FILEPATH);
@@ -1940,7 +1962,7 @@ static void WM_OT_save_mainfile(wmOperatorType *ot)
ot->invoke= wm_save_mainfile_invoke;
ot->exec= wm_save_as_mainfile_exec;
ot->check= blend_save_check;
- ot->poll= NULL;
+ /* ommit window poll so this can work in background mode */
WM_operator_properties_filesel(ot, FOLDERFILE|BLENDERFILE, FILE_BLENDER, FILE_SAVE, WM_FILESEL_FILEPATH);
RNA_def_boolean(ot->srna, "compress", 0, "Compress", "Write compressed .blend file");
@@ -2244,6 +2266,13 @@ int WM_border_select_modal(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
+int WM_border_select_cancel(bContext *C, wmOperator *op)
+{
+ wm_gesture_end(C, op);
+
+ return OPERATOR_CANCELLED;
+}
+
/* **************** circle gesture *************** */
/* works now only for selection or modal paint stuff, calls exec while hold mouse, exit on release */
@@ -2340,6 +2369,13 @@ int WM_gesture_circle_modal(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
+int WM_gesture_circle_cancel(bContext *C, wmOperator *op)
+{
+ wm_gesture_end(C, op);
+
+ return OPERATOR_CANCELLED;
+}
+
#if 0
/* template to copy from */
void WM_OT_circle_gesture(wmOperatorType *ot)
@@ -2556,6 +2592,20 @@ int WM_gesture_lines_modal(bContext *C, wmOperator *op, wmEvent *event)
return WM_gesture_lasso_modal(C, op, event);
}
+int WM_gesture_lasso_cancel(bContext *C, wmOperator *op)
+{
+ wm_gesture_end(C, op);
+
+ return OPERATOR_CANCELLED;
+}
+
+int WM_gesture_lines_cancel(bContext *C, wmOperator *op)
+{
+ wm_gesture_end(C, op);
+
+ return OPERATOR_CANCELLED;
+}
+
#if 0
/* template to copy from */
@@ -2677,6 +2727,13 @@ int WM_gesture_straightline_modal(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
+int WM_gesture_straightline_cancel(bContext *C, wmOperator *op)
+{
+ wm_gesture_end(C, op);
+
+ return OPERATOR_CANCELLED;
+}
+
#if 0
/* template to copy from */
void WM_OT_straightline_gesture(wmOperatorType *ot)
@@ -3060,10 +3117,31 @@ static void radial_control_set_value(RadialControl *rc, float val)
}
}
+static int radial_control_cancel(bContext *C, wmOperator *op)
+{
+ RadialControl *rc = op->customdata;
+ wmWindowManager *wm = CTX_wm_manager(C);
+
+ WM_paint_cursor_end(wm, rc->cursor);
+
+ /* restore original paint cursors */
+ wm->paintcursors = rc->orig_paintcursors;
+
+ /* not sure if this is a good notifier to use;
+ intended purpose is to update the UI so that the
+ new value is displayed in sliders/numfields */
+ WM_event_add_notifier(C, NC_WINDOW, NULL);
+
+ glDeleteTextures(1, &rc->gltex);
+
+ MEM_freeN(rc);
+
+ return OPERATOR_CANCELLED;
+}
+
static int radial_control_modal(bContext *C, wmOperator *op, wmEvent *event)
{
RadialControl *rc = op->customdata;
- wmWindowManager *wm;
float new_value, dist, zoom[2];
float delta[2], snap, ret = OPERATOR_RUNNING_MODAL;
@@ -3125,23 +3203,8 @@ static int radial_control_modal(bContext *C, wmOperator *op, wmEvent *event)
ED_region_tag_redraw(CTX_wm_region(C));
- if(ret != OPERATOR_RUNNING_MODAL) {
- wm = CTX_wm_manager(C);
-
- WM_paint_cursor_end(wm, rc->cursor);
-
- /* restore original paint cursors */
- wm->paintcursors = rc->orig_paintcursors;
-
- /* not sure if this is a good notifier to use;
- intended purpose is to update the UI so that the
- new value is displayed in sliders/numfields */
- WM_event_add_notifier(C, NC_WINDOW, NULL);
-
- glDeleteTextures(1, &rc->gltex);
-
- MEM_freeN(rc);
- }
+ if(ret != OPERATOR_RUNNING_MODAL)
+ radial_control_cancel(C, op);
return ret;
}
@@ -3153,6 +3216,7 @@ static void WM_OT_radial_control(wmOperatorType *ot)
ot->invoke= radial_control_invoke;
ot->modal= radial_control_modal;
+ ot->cancel= radial_control_cancel;
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
index 82fe42f2b42..9ee39132521 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -271,9 +271,11 @@ void wm_window_close(bContext *C, wmWindowManager *wm, wmWindow *win)
void wm_window_title(wmWindowManager *wm, wmWindow *win)
{
- /* handle the 'temp' window */
+ /* handle the 'temp' window, only set title when not set before */
if(win->screen && win->screen->temp) {
- GHOST_SetTitle(win->ghostwin, "Blender");
+ char *title= GHOST_GetTitle(win->ghostwin);
+ if(title==NULL || title[0]==0)
+ GHOST_SetTitle(win->ghostwin, "Blender");
}
else {
diff --git a/source/blenderplayer/CMakeLists.txt b/source/blenderplayer/CMakeLists.txt
index 901aaea3eca..5fe045fda10 100644
--- a/source/blenderplayer/CMakeLists.txt
+++ b/source/blenderplayer/CMakeLists.txt
@@ -183,6 +183,12 @@ endif()
message(STATUS "Player Skipping: (${REM_MSG})")
endif()
target_link_libraries(blenderplayer ${BLENDER_SORTED_LIBS})
+
+ unset(SEARCHLIB)
+ unset(SORTLIB)
+ unset(REMLIB)
+ unset(REM_MSG)
+
# else()
# target_link_libraries(blenderplayer ${BLENDER_LINK_LIBS})
# endif()
diff --git a/source/blenderplayer/bad_level_call_stubs/CMakeLists.txt b/source/blenderplayer/bad_level_call_stubs/CMakeLists.txt
index 2cc6dbc8255..15c3b2a4743 100644
--- a/source/blenderplayer/bad_level_call_stubs/CMakeLists.txt
+++ b/source/blenderplayer/bad_level_call_stubs/CMakeLists.txt
@@ -46,7 +46,9 @@ set(SRC
)
if(WITH_BUILDINFO)
- list(APPEND SRC ../../creator/buildinfo.c)
+ list(APPEND SRC
+ ../../creator/buildinfo.c
+ )
add_definitions(-DBUILD_DATE)
endif()
diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt
index c3eae586599..85fda11bd66 100644
--- a/source/creator/CMakeLists.txt
+++ b/source/creator/CMakeLists.txt
@@ -81,6 +81,10 @@ if(WITH_PYTHON)
endif()
endif()
+if(WITH_HEADLESS)
+ add_definitions(-DWITH_HEADLESS)
+endif()
+
if(WITH_GAMEENGINE)
blender_include_dirs(../gameengine/BlenderRoutines)
@@ -847,6 +851,12 @@ endif()
message(STATUS "Blender Skipping: (${REM_MSG})")
endif()
target_link_libraries(blender ${BLENDER_SORTED_LIBS})
+
+ unset(SEARCHLIB)
+ unset(SORTLIB)
+ unset(REMLIB)
+ unset(REM_MSG)
+
#else()
# target_link_libraries(blender ${BLENDER_LINK_LIBS})
#endif()
diff --git a/source/creator/SConscript b/source/creator/SConscript
index 79e03c8dddc..80428ba7bb6 100644
--- a/source/creator/SConscript
+++ b/source/creator/SConscript
@@ -1,48 +1,3 @@
#!/usr/bin/python
-Import ('env')
-import os
-sources = 'creator.c'
-
-incs = '#/intern/guardedalloc ../blender/blenlib ../blender/blenkernel'
-incs += ' ../blender/editors/include ../blender/blenloader ../blender/imbuf'
-incs += ' ../blender/renderconverter ../blender/render/extern/include ../blender/windowmanager'
-incs += ' ../blender/makesdna ../blender/makesrna'
-incs += ' ../gameengine/BlenderRoutines #/extern/glew/include ../blender/gpu'
-incs += ' ' + env['BF_OPENGL_INC']
-
-defs = []
-if env['WITH_BF_QUICKTIME']:
- incs += ' ' + env['BF_QUICKTIME_INC']
- defs.append('WITH_QUICKTIME')
-
-if env['WITH_BF_BINRELOC']:
- incs += ' ../../extern/binreloc/include'
- defs.append('WITH_BINRELOC')
-
-if env['WITH_BF_OPENEXR']:
- defs.append('WITH_OPENEXR')
-
-if env['WITH_BF_TIFF']:
- defs.append('WITH_TIFF')
-
-if not env['WITH_BF_SDL']:
- defs.append('DISABLE_SDL')
-
-if env['WITH_BF_PYTHON']:
- incs += ' ../blender/python'
- defs.append('WITH_PYTHON')
- if env['BF_DEBUG']:
- defs.append('_DEBUG')
-
-if env['BF_BUILDINFO']:
- defs.append('BUILD_DATE')
- defs.append('NAN_BUILDINFO')
-
-if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'):
- incs += ' ' + env['BF_PTHREADS_INC']
-
-if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'):
- incs += ' ' + env['BF_PTHREADS_INC']
-
-env.BlenderLib ( libname = 'bf_creator', sources = Split(sources), includes = Split(incs), defines = defs, libtype='core', priority = 0 )
+# dummy, code has been moved to Blender.creator()
diff --git a/source/creator/creator.c b/source/creator/creator.c
index 6e9ecf234fc..8b405d2d4b8 100644
--- a/source/creator/creator.c
+++ b/source/creator/creator.c
@@ -538,7 +538,7 @@ static int set_output(int argc, const char **argv, void *data)
if (argc >= 1){
if (CTX_data_scene(C)) {
Scene *scene= CTX_data_scene(C);
- BLI_strncpy(scene->r.pic, argv[1], FILE_MAXDIR);
+ BLI_strncpy(scene->r.pic, argv[1], sizeof(scene->r.pic));
} else {
printf("\nError: no blend loaded. cannot use '-o / --render-output'.\n");
}
@@ -1215,7 +1215,7 @@ int main(int argc, const char **argv)
setuid(getuid()); /* end superuser */
#endif
-#ifdef WITH_PYTHON_MODULE
+#if defined(WITH_PYTHON_MODULE) || defined(WITH_HEADLESS)
G.background= 1; /* python module mode ALWAYS runs in background mode (for now) */
#else
/* for all platforms, even windos has it! */
diff --git a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
index cac801c80ef..1eeb7c0f94b 100644
--- a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
+++ b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
@@ -258,7 +258,7 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *c
draw_letterbox = 1;
}
else {
- camzoom = BKE_screen_view3d_zoom_to_fac(rv3d->camzoom)*4.0f;
+ camzoom = 1.0 / BKE_screen_view3d_zoom_to_fac(rv3d->camzoom);
}
}
else {
diff --git a/source/gameengine/Converter/KX_ConvertActuators.cpp b/source/gameengine/Converter/KX_ConvertActuators.cpp
index 7bd51fef9f0..1a8368a12fa 100644
--- a/source/gameengine/Converter/KX_ConvertActuators.cpp
+++ b/source/gameengine/Converter/KX_ConvertActuators.cpp
@@ -77,6 +77,7 @@
/* This little block needed for linking to Blender... */
#include "BKE_text.h"
#include "BLI_blenlib.h"
+#include "BLI_math_base.h"
#define FILE_MAX 240 // repeated here to avoid dependency from BKE_utildefines.h
@@ -283,7 +284,8 @@ void BL_ConvertActuators(char* maggiename,
camact->height,
camact->min,
camact->max,
- camact->axis=='x');
+ camact->axis=='x',
+ camact->damping);
baseact = tmpcamact;
}
break;
@@ -394,7 +396,7 @@ void BL_ConvertActuators(char* maggiename,
new KX_SoundActuator(gameobj,
snd_sound,
soundact->volume,
- (float)(exp((soundact->pitch / 12.0) * log(2.0))),
+ (float)(exp((soundact->pitch / 12.0) * M_LN2)),
is3d,
settings,
soundActuatorType);
diff --git a/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp b/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp
index 0a65fc1584a..c270d9a312b 100644
--- a/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp
+++ b/source/gameengine/GameLogic/SCA_2DFilterActuator.cpp
@@ -55,10 +55,10 @@ SCA_2DFilterActuator::SCA_2DFilterActuator(
m_rasterizer(rasterizer),
m_scene(scene)
{
- m_gameObj = NULL;
+ m_gameobj = NULL;
if(gameobj){
m_propNames = gameobj->GetPropertyNames();
- m_gameObj = gameobj;
+ m_gameobj = gameobj;
}
}
@@ -91,7 +91,7 @@ bool SCA_2DFilterActuator::Update()
}
else if(m_type < RAS_2DFilterManager::RAS_2DFILTER_NUMBER_OF_FILTERS)
{
- m_scene->Update2DFilter(m_propNames, m_gameObj, m_type, m_int_arg, m_shaderText);
+ m_scene->Update2DFilter(m_propNames, m_gameobj, m_type, m_int_arg, m_shaderText);
}
// once the filter is in place, no need to update it again => disable the actuator
return false;
diff --git a/source/gameengine/GameLogic/SCA_2DFilterActuator.h b/source/gameengine/GameLogic/SCA_2DFilterActuator.h
index 87d2e8ddbcf..7f31c1713f4 100644
--- a/source/gameengine/GameLogic/SCA_2DFilterActuator.h
+++ b/source/gameengine/GameLogic/SCA_2DFilterActuator.h
@@ -42,7 +42,6 @@ class SCA_2DFilterActuator : public SCA_IActuator
private:
vector<STR_String> m_propNames;
- void * m_gameObj;
RAS_2DFilterManager::RAS_2DFILTER_MODE m_type;
short m_disableMotionBlur;
float m_float_arg;
diff --git a/source/gameengine/Ketsji/KX_CameraActuator.cpp b/source/gameengine/Ketsji/KX_CameraActuator.cpp
index d68cb453fe8..ebb291b2284 100644
--- a/source/gameengine/Ketsji/KX_CameraActuator.cpp
+++ b/source/gameengine/Ketsji/KX_CameraActuator.cpp
@@ -54,14 +54,16 @@ KX_CameraActuator::KX_CameraActuator(
float hght,
float minhght,
float maxhght,
- bool xytog
+ bool xytog,
+ float damping
):
SCA_IActuator(gameobj, KX_ACT_CAMERA),
m_ob (obj),
m_height (hght),
m_minHeight (minhght),
m_maxHeight (maxhght),
- m_x (xytog)
+ m_x (xytog),
+ m_damping (damping)
{
if (m_ob)
m_ob->RegisterActuator(this);
@@ -283,7 +285,7 @@ bool KX_CameraActuator::Update(double curtime, bool frame)
}
inp= fp1[0]*fp2[0] + fp1[1]*fp2[1] + fp1[2]*fp2[2];
- fac= (-1.0 + inp)/32.0;
+ fac= (-1.0 + inp) * m_damping;
from[0]+= fac*fp1[0];
from[1]+= fac*fp1[1];
@@ -390,6 +392,7 @@ PyAttributeDef KX_CameraActuator::Attributes[] = {
KX_PYATTRIBUTE_FLOAT_RW("height",-FLT_MAX,FLT_MAX,KX_CameraActuator,m_height),
KX_PYATTRIBUTE_BOOL_RW("useXY",KX_CameraActuator,m_x),
KX_PYATTRIBUTE_RW_FUNCTION("object", KX_CameraActuator, pyattr_get_object, pyattr_set_object),
+ KX_PYATTRIBUTE_FLOAT_RW("damping",0.f,10.f,KX_CameraActuator,m_damping),
{NULL}
};
diff --git a/source/gameengine/Ketsji/KX_CameraActuator.h b/source/gameengine/Ketsji/KX_CameraActuator.h
index d59fcff9370..f844f6418b8 100644
--- a/source/gameengine/Ketsji/KX_CameraActuator.h
+++ b/source/gameengine/Ketsji/KX_CameraActuator.h
@@ -73,6 +73,9 @@ private :
/** xy toggle (pick one): true == x, false == y */
bool m_x;
+
+ /** damping (float), */
+ float m_damping;
/* get the KX_IGameObject with this name */
CValue *findObject(char *obName);
@@ -95,7 +98,8 @@ private :
float hght,
float minhght,
float maxhght,
- bool xytog
+ bool xytog,
+ float damping
);
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsController.h b/source/gameengine/Physics/Bullet/CcdPhysicsController.h
index 97dc65c5850..08445654916 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsController.h
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsController.h
@@ -226,18 +226,43 @@ struct CcdConstructionInfo
CcdConstructionInfo()
- : m_localInertiaTensor(1.f, 1.f, 1.f),
+ :m_localInertiaTensor(1.f, 1.f, 1.f),
m_gravity(0,0,0),
m_scaling(1.f,1.f,1.f),
m_mass(0.f),
- m_clamp_vel_min(-1.f),
- m_clamp_vel_max(-1.f),
+ m_clamp_vel_min(-1.f),
+ m_clamp_vel_max(-1.f),
m_restitution(0.1f),
m_friction(0.5f),
m_linearDamping(0.1f),
m_angularDamping(0.1f),
m_margin(0.06f),
m_gamesoftFlag(0),
+ m_soft_linStiff(1.f),
+ m_soft_angStiff(1.f),
+ m_soft_volume(1.f),
+ m_soft_viterations(0),
+ m_soft_piterations(1),
+ m_soft_diterations(0),
+ m_soft_citerations(4),
+ m_soft_kSRHR_CL(0.1f),
+ m_soft_kSKHR_CL(1.f),
+ m_soft_kSSHR_CL(0.5f),
+ m_soft_kSR_SPLT_CL(0.5f),
+ m_soft_kSK_SPLT_CL(0.5f),
+ m_soft_kSS_SPLT_CL(0.5f),
+ m_soft_kVCF(1.f),
+ m_soft_kDP(0.f),
+ m_soft_kDG(0.f),
+ m_soft_kLF(0.f),
+ m_soft_kPR(0.f),
+ m_soft_kVC(0.f),
+ m_soft_kDF(0.2f),
+ m_soft_kMT(0),
+ m_soft_kCHR(1.0f),
+ m_soft_kKHR(0.1f),
+ m_soft_kSHR(1.0f),
+ m_soft_kAHR(0.7f),
m_collisionFlags(0),
m_bRigid(false),
m_bSoft(false),
@@ -252,38 +277,13 @@ struct CcdConstructionInfo
m_inertiaFactor(1.f),
m_do_anisotropic(false),
m_anisotropicFriction(1.f,1.f,1.f),
- m_contactProcessingThreshold(1e10f),
- m_soft_linStiff(1.f),
- m_soft_angStiff(1.f),
- m_soft_volume(1.f),
- m_soft_viterations(0),
- m_soft_piterations(1),
- m_soft_diterations(0),
- m_soft_citerations(4),
m_do_fh(false),
m_do_rot_fh(false),
m_fh_spring(0.f),
m_fh_damping(0.f),
m_fh_distance(1.f),
m_fh_normal(false),
- m_soft_kVCF(1.f),
- m_soft_kDG(0.f),
- m_soft_kLF(0.f),
- m_soft_kDP(0.f),
- m_soft_kPR(0.f),
- m_soft_kVC(0.f),
- m_soft_kDF(0.2f),
- m_soft_kMT(0),
- m_soft_kCHR(1.0f),
- m_soft_kKHR(0.1f),
- m_soft_kSHR(1.0f),
- m_soft_kAHR(0.7f),
- m_soft_kSRHR_CL(0.1f),
- m_soft_kSKHR_CL(1.f),
- m_soft_kSSHR_CL(0.5f),
- m_soft_kSR_SPLT_CL(0.5f),
- m_soft_kSK_SPLT_CL(0.5f),
- m_soft_kSS_SPLT_CL(0.5f)
+ m_contactProcessingThreshold(1e10f)
{
}
diff --git a/source/tests/CMakeLists.txt b/source/tests/CMakeLists.txt
index 97e46bd44f2..48053aa9d96 100644
--- a/source/tests/CMakeLists.txt
+++ b/source/tests/CMakeLists.txt
@@ -68,21 +68,21 @@ add_test(script_run_operators ${TEST_BLENDER_EXE}
add_test(import_obj_cube ${TEST_BLENDER_EXE}
--python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py --
--run={'FINISHED'}&bpy.ops.import_scene.obj\(filepath='${TEST_SRC_DIR}/io_tests/obj/cube.obj'\)
- --md5=4d090508b812b5e08168aa2614746bda --md5_method=SCENE
+ --md5=39cce4bacac2d1b18fc470380279bc15 --md5_method=SCENE
--write-blend=${TEST_OUT_DIR}/import_obj_cube.blend
)
add_test(import_obj_nurbs_cyclic ${TEST_BLENDER_EXE}
--python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py --
--run={'FINISHED'}&bpy.ops.import_scene.obj\(filepath='${TEST_SRC_DIR}/io_tests/obj/nurbs_cyclic.obj'\)
- --md5=9e0da7b65b4c4f818a203d56af2d3a4b --md5_method=SCENE
+ --md5=ad3c307e5883224a0492378cd32691ab --md5_method=SCENE
--write-blend=${TEST_OUT_DIR}/import_obj_nurbs_cyclic.blend
)
add_test(import_obj_makehuman ${TEST_BLENDER_EXE}
--python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py --
--run={'FINISHED'}&bpy.ops.import_scene.obj\(filepath='${TEST_SRC_DIR}/io_tests/obj/makehuman.obj'\)
- --md5=e0829dc078b0789e1d81f1071235bc4f --md5_method=SCENE
+ --md5=c9f78b185e58358daa4ecaecfa75464e --md5_method=SCENE
--write-blend=${TEST_OUT_DIR}/import_obj_makehuman.blend
)
@@ -93,7 +93,7 @@ add_test(export_obj_cube ${TEST_BLENDER_EXE}
--run={'FINISHED'}&bpy.ops.export_scene.obj\(filepath='${TEST_OUT_DIR}/export_obj_cube.obj',use_selection=False\)
--md5_source=${TEST_OUT_DIR}/export_obj_cube.obj
--md5_source=${TEST_OUT_DIR}/export_obj_cube.mtl
- --md5=f0580f0e5d7b379e0460f11d8fde244d --md5_method=FILE
+ --md5=70bdc394c2726203ad26c085176e3484 --md5_method=FILE
)
add_test(export_obj_nurbs ${TEST_BLENDER_EXE}
@@ -102,7 +102,7 @@ add_test(export_obj_nurbs ${TEST_BLENDER_EXE}
--run={'FINISHED'}&bpy.ops.export_scene.obj\(filepath='${TEST_OUT_DIR}/export_obj_nurbs.obj',use_selection=False,use_nurbs=True\)
--md5_source=${TEST_OUT_DIR}/export_obj_nurbs.obj
--md5_source=${TEST_OUT_DIR}/export_obj_nurbs.mtl
- --md5=aa00875343e0feea449739146d26d7d0 --md5_method=FILE
+ --md5=a733ae4fa4a591ea9b0912da3af042de --md5_method=FILE
)
add_test(export_obj_all_objects ${TEST_BLENDER_EXE}
@@ -111,7 +111,7 @@ add_test(export_obj_all_objects ${TEST_BLENDER_EXE}
--run={'FINISHED'}&bpy.ops.export_scene.obj\(filepath='${TEST_OUT_DIR}/export_obj_all_objects.obj',use_selection=False,use_nurbs=True\)
--md5_source=${TEST_OUT_DIR}/export_obj_all_objects.obj
--md5_source=${TEST_OUT_DIR}/export_obj_all_objects.mtl
- --md5=4c93980ecfb7d02ca68d3da8e2fced69 --md5_method=FILE
+ --md5=01c123948efadc6a71ab2c09a5925756 --md5_method=FILE
)
@@ -172,21 +172,21 @@ add_test(import_stl_knot_max_simplified ${TEST_BLENDER_EXE}
add_test(import_x3d_cube ${TEST_BLENDER_EXE}
--python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py --
--run={'FINISHED'}&bpy.ops.import_scene.x3d\(filepath='${TEST_SRC_DIR}/io_tests/x3d/color_cube.x3d'\)
- --md5=330c0cf6e8c44d5fe5b662d30b75be89 --md5_method=SCENE
+ --md5=2ed64325dd3d62be6ce43c64219376ec --md5_method=SCENE
--write-blend=${TEST_OUT_DIR}/import_x3d_cube.blend
)
add_test(import_x3d_teapot ${TEST_BLENDER_EXE}
--python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py --
--run={'FINISHED'}&bpy.ops.import_scene.x3d\(filepath='${TEST_SRC_DIR}/io_tests/x3d/teapot.x3d'\)
- --md5=b2f02157bc918b54b835d1e6ece70423 --md5_method=SCENE
+ --md5=8b8b386900b8e3d2c036a38c625f4079 --md5_method=SCENE
--write-blend=${TEST_OUT_DIR}/import_x3d_teapot.blend
)
add_test(import_x3d_suzanne_material ${TEST_BLENDER_EXE}
--python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py --
--run={'FINISHED'}&bpy.ops.import_scene.x3d\(filepath='${TEST_SRC_DIR}/io_tests/x3d/suzanne_material.x3d'\)
- --md5=11837901cbbfabef52b6ab4f26fe97b3 --md5_method=SCENE
+ --md5=999129ba835f0ccb98c4bb299f6c2fef --md5_method=SCENE
--write-blend=${TEST_OUT_DIR}/import_x3d_suzanne_material.blend
)
@@ -196,7 +196,7 @@ add_test(export_x3d_cube ${TEST_BLENDER_EXE}
--python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py --
--run={'FINISHED'}&bpy.ops.export_scene.x3d\(filepath='${TEST_OUT_DIR}/export_x3d_cube.x3d',use_selection=False\)
--md5_source=${TEST_OUT_DIR}/export_x3d_cube.x3d
- --md5=9198ca86f19b68a4f1eb75bb48cb3dea --md5_method=FILE
+ --md5=30d2b056c004144cd4a0d172484a66f3 --md5_method=FILE
)
add_test(export_x3d_nurbs ${TEST_BLENDER_EXE}
@@ -204,7 +204,7 @@ add_test(export_x3d_nurbs ${TEST_BLENDER_EXE}
--python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py --
--run={'FINISHED'}&bpy.ops.export_scene.x3d\(filepath='${TEST_OUT_DIR}/export_x3d_nurbs.x3d',use_selection=False\)
--md5_source=${TEST_OUT_DIR}/export_x3d_nurbs.x3d
- --md5=078c0ca5a08f123cd2cdac48afb54853 --md5_method=FILE
+ --md5=7c15afe7b0cf007b842a925508b7d966 --md5_method=FILE
)
add_test(export_x3d_all_objects ${TEST_BLENDER_EXE}
@@ -212,7 +212,7 @@ add_test(export_x3d_all_objects ${TEST_BLENDER_EXE}
--python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py --
--run={'FINISHED'}&bpy.ops.export_scene.x3d\(filepath='${TEST_OUT_DIR}/export_x3d_all_objects.x3d',use_selection=False\)
--md5_source=${TEST_OUT_DIR}/export_x3d_all_objects.x3d
- --md5=090f4f36c450826a043f9cd074d9cbb4 --md5_method=FILE
+ --md5=d7d6574e833f3f051b65ef4577485fa9 --md5_method=FILE
)
@@ -228,14 +228,14 @@ add_test(import_3ds_cube ${TEST_BLENDER_EXE}
add_test(import_3ds_hierarchy_lara ${TEST_BLENDER_EXE}
--python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py --
--run={'FINISHED'}&bpy.ops.import_scene.autodesk_3ds\(filepath='${TEST_SRC_DIR}/io_tests/3ds/hierarchy_lara.3ds'\)
- --md5=2e9812099b26ad607fdcf4c7be918c71 --md5_method=SCENE
+ --md5=766c873d9fdb5f190e43796cfbae63b6 --md5_method=SCENE
--write-blend=${TEST_OUT_DIR}/import_3ds_hierarchy_lara.blend
)
add_test(import_3ds_hierarchy_greek_trireme ${TEST_BLENDER_EXE}
--python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py --
--run={'FINISHED'}&bpy.ops.import_scene.autodesk_3ds\(filepath='${TEST_SRC_DIR}/io_tests/3ds/hierarchy_greek_trireme.3ds'\)
- --md5=d05b922d7be20356d8409d1f768a3a9a --md5_method=SCENE
+ --md5=b62ee30101e8999cb91ef4f8a8760056 --md5_method=SCENE
--write-blend=${TEST_OUT_DIR}/import_3ds_hierarchy_greek_trireme.blend
)
@@ -261,7 +261,7 @@ add_test(export_3ds_all_objects ${TEST_BLENDER_EXE}
--python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py --
--run={'FINISHED'}&bpy.ops.export_scene.autodesk_3ds\(filepath='${TEST_OUT_DIR}/export_3ds_all_objects.3ds',use_selection=False\)
--md5_source=${TEST_OUT_DIR}/export_3ds_all_objects.3ds
- --md5=87349a4699f1006e8194fb0ac05ac9c8 --md5_method=FILE
+ --md5=cdf8fa8475fda0b9ef565ac09339254b --md5_method=FILE
)
@@ -273,7 +273,7 @@ add_test(export_fbx_cube ${TEST_BLENDER_EXE}
--python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py --
--run={'FINISHED'}&bpy.ops.export_scene.fbx\(filepath='${TEST_OUT_DIR}/export_fbx_cube.fbx',use_selection=False,use_metadata=False\)
--md5_source=${TEST_OUT_DIR}/export_fbx_cube.fbx
- --md5=b2428e11b9ae650819f8d8b38cd869f7 --md5_method=FILE
+ --md5=642a5a1fa199d5b9bbf1643519ae974d --md5_method=FILE
)
add_test(export_fbx_nurbs ${TEST_BLENDER_EXE}
@@ -281,7 +281,7 @@ add_test(export_fbx_nurbs ${TEST_BLENDER_EXE}
--python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py --
--run={'FINISHED'}&bpy.ops.export_scene.fbx\(filepath='${TEST_OUT_DIR}/export_fbx_nurbs.fbx',use_selection=False,use_metadata=False\)
--md5_source=${TEST_OUT_DIR}/export_fbx_nurbs.fbx
- --md5=741b536e98d6b105952766d0f290f270 --md5_method=FILE
+ --md5=ec1e8965bdbc3bf70707d77f82c2cb9c --md5_method=FILE
)
add_test(export_fbx_all_objects ${TEST_BLENDER_EXE}
@@ -289,5 +289,5 @@ add_test(export_fbx_all_objects ${TEST_BLENDER_EXE}
--python ${CMAKE_CURRENT_LIST_DIR}/bl_test.py --
--run={'FINISHED'}&bpy.ops.export_scene.fbx\(filepath='${TEST_OUT_DIR}/export_fbx_all_objects.fbx',use_selection=False,use_metadata=False\)
--md5_source=${TEST_OUT_DIR}/export_fbx_all_objects.fbx
- --md5=d6b8b027cd2a0e99d88e5c3d77932748 --md5_method=FILE
+ --md5=af3b65665687ac92e4aba07b017d87fe --md5_method=FILE
)
diff --git a/source/tests/bl_load_py_modules.py b/source/tests/bl_load_py_modules.py
index 5a65578d8d3..a88edd5f1fe 100644
--- a/source/tests/bl_load_py_modules.py
+++ b/source/tests/bl_load_py_modules.py
@@ -65,6 +65,10 @@ def load_modules():
# paths blender stores scripts in.
paths = bpy.utils.script_paths()
+ print("Paths:")
+ for script_path in paths:
+ print("\t'%s'" % script_path)
+
#
# find all sys.path we added
for script_path in paths:
@@ -74,11 +78,18 @@ def load_modules():
#
# collect modules from our paths.
+ module_names = set()
for mod_dir in module_paths:
# print("mod_dir", mod_dir)
for mod, mod_full in bpy.path.module_names(mod_dir):
+ if mod in module_names:
+ raise Exception("Module found twice %r" % mod)
+
modules.append(__import__(mod))
+ module_names.add(mod)
+ del module_names
+
#
# now submodules
for m in modules: