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:
authorMiika Hamalainen <blender@miikah.org>2011-08-03 22:47:20 +0400
committerMiika Hamalainen <blender@miikah.org>2011-08-03 22:47:20 +0400
commitdaea8a28ae11131c86d98f20b819ad33036b875a (patch)
tree85faba3c1aaa0c45db61c714e1337c8c008c3adc
parent8394f65d4a6019ae623fe32268a769463a189b9e (diff)
parent79c87852d2a2b07ba3cb411e00fd0fb4aaee008a (diff)
Merge with trunk r39000
-rw-r--r--CMakeLists.txt109
-rw-r--r--SConstruct12
-rw-r--r--build_files/buildbot/config/user-config-i686.py8
-rw-r--r--build_files/buildbot/config/user-config-player-i686.py19
-rw-r--r--build_files/buildbot/config/user-config-player-x86_64.py19
-rw-r--r--build_files/buildbot/config/user-config-x86_64.py8
-rw-r--r--build_files/buildbot/master.cfg1
-rw-r--r--build_files/buildbot/slave_compile.py28
-rw-r--r--build_files/buildbot/slave_pack.py28
-rw-r--r--build_files/cmake/Modules/FindSpacenav.cmake70
-rwxr-xr-xbuild_files/cmake/cmake_consistency_check.py14
-rwxr-xr-xbuild_files/cmake/cmake_netbeans_project.py13
-rwxr-xr-xbuild_files/cmake/cmake_qtcreator_project.py12
-rw-r--r--build_files/cmake/macros.cmake4
-rw-r--r--build_files/scons/config/darwin-config.py7
-rw-r--r--build_files/scons/config/linux2-config.py8
-rw-r--r--build_files/scons/config/win32-vc-config.py3
-rw-r--r--build_files/scons/config/win64-vc-config.py3
-rw-r--r--build_files/scons/tools/Blender.py11
-rw-r--r--build_files/scons/tools/btools.py15
-rw-r--r--doc/python_api/blender-org/static/default.css_t2
-rw-r--r--doc/python_api/examples/bge.constraints.py12
-rw-r--r--doc/python_api/examples/bge.texture.1.py16
-rw-r--r--doc/python_api/examples/bge.texture.py10
-rw-r--r--doc/python_api/examples/blf.py15
-rw-r--r--doc/python_api/examples/mathutils.Vector.py13
-rw-r--r--doc/python_api/rst/bge.constraints.rst238
-rw-r--r--doc/python_api/rst/bge.events.rst4
-rw-r--r--doc/python_api/rst/bge.logic.rst5
-rw-r--r--doc/python_api/rst/bge.render.rst14
-rw-r--r--doc/python_api/rst/bge.texture.rst8
-rw-r--r--doc/python_api/rst/bge.types.rst4
-rw-r--r--doc/python_api/rst/bgl.rst9
-rw-r--r--doc/python_api/sphinx_doc_gen.py19
-rwxr-xr-xdoc/python_api/sphinx_doc_gen.sh7
-rw-r--r--intern/ghost/CMakeLists.txt45
-rw-r--r--intern/ghost/GHOST_C-api.h15
-rw-r--r--intern/ghost/GHOST_ISystem.h16
-rw-r--r--intern/ghost/GHOST_Types.h57
-rw-r--r--intern/ghost/SConscript22
-rw-r--r--intern/ghost/intern/GHOST_C-api.cpp17
-rw-r--r--intern/ghost/intern/GHOST_DisplayManagerWin32.cpp5
-rw-r--r--intern/ghost/intern/GHOST_DropTargetWin32.cpp1
-rw-r--r--intern/ghost/intern/GHOST_DropTargetWin32.h1
-rw-r--r--intern/ghost/intern/GHOST_EventManager.cpp2
-rw-r--r--intern/ghost/intern/GHOST_EventNDOF.h56
-rw-r--r--intern/ghost/intern/GHOST_NDOFManager.cpp506
-rw-r--r--intern/ghost/intern/GHOST_NDOFManager.h145
-rw-r--r--intern/ghost/intern/GHOST_NDOFManagerCocoa.h50
-rw-r--r--intern/ghost/intern/GHOST_NDOFManagerCocoa.mm172
-rw-r--r--intern/ghost/intern/GHOST_NDOFManagerWin32.cpp41
-rw-r--r--intern/ghost/intern/GHOST_NDOFManagerWin32.h40
-rw-r--r--intern/ghost/intern/GHOST_NDOFManagerX11.cpp106
-rw-r--r--intern/ghost/intern/GHOST_NDOFManagerX11.h49
-rw-r--r--intern/ghost/intern/GHOST_System.cpp43
-rw-r--r--intern/ghost/intern/GHOST_System.h29
-rw-r--r--intern/ghost/intern/GHOST_SystemCocoa.h7
-rw-r--r--intern/ghost/intern/GHOST_SystemCocoa.mm14
-rw-r--r--intern/ghost/intern/GHOST_SystemPathsWin32.cpp7
-rw-r--r--intern/ghost/intern/GHOST_SystemPathsWin32.h2
-rw-r--r--intern/ghost/intern/GHOST_SystemWin32.cpp434
-rw-r--r--intern/ghost/intern/GHOST_SystemWin32.h133
-rw-r--r--intern/ghost/intern/GHOST_SystemX11.cpp73
-rw-r--r--intern/ghost/intern/GHOST_SystemX11.h5
-rw-r--r--intern/ghost/intern/GHOST_TaskbarWin32.h10
-rw-r--r--intern/ghost/intern/GHOST_WindowWin32.h14
-rw-r--r--release/scripts/modules/addon_utils.py46
-rw-r--r--release/scripts/modules/bpy/__init__.py8
-rw-r--r--release/scripts/modules/bpy/path.py90
-rw-r--r--release/scripts/modules/bpy/utils.py81
-rw-r--r--release/scripts/modules/bpy_extras/__init__.py4
-rw-r--r--release/scripts/modules/bpy_extras/image_utils.py19
-rw-r--r--release/scripts/modules/bpy_extras/io_utils.py215
-rw-r--r--release/scripts/modules/bpy_extras/mesh_utils.py34
-rw-r--r--release/scripts/modules/bpy_extras/object_utils.py41
-rw-r--r--release/scripts/modules/bpy_extras/view3d_utils.py28
-rw-r--r--release/scripts/modules/bpy_types.py14
-rw-r--r--release/scripts/modules/keyingsets_utils.py9
-rw-r--r--release/scripts/presets/ffmpeg/xvid.py3
-rw-r--r--release/scripts/startup/bl_operators/add_mesh_torus.py17
-rw-r--r--release/scripts/startup/bl_operators/image.py34
-rw-r--r--release/scripts/startup/bl_operators/mesh.py8
-rw-r--r--release/scripts/startup/bl_operators/object.py232
-rw-r--r--release/scripts/startup/bl_operators/object_align.py121
-rw-r--r--release/scripts/startup/bl_operators/object_quick_effects.py134
-rw-r--r--release/scripts/startup/bl_operators/object_randomize_transform.py89
-rw-r--r--release/scripts/startup/bl_operators/presets.py53
-rw-r--r--release/scripts/startup/bl_operators/screen_play_rendered_anim.py103
-rw-r--r--release/scripts/startup/bl_operators/uvcalc_smart_project.py4
-rw-r--r--release/scripts/startup/bl_ui/properties_data_empty.py4
-rw-r--r--release/scripts/startup/bl_ui/properties_data_modifier.py1
-rw-r--r--release/scripts/startup/bl_ui/properties_material.py12
-rw-r--r--release/scripts/startup/bl_ui/properties_world.py2
-rw-r--r--release/scripts/startup/bl_ui/space_info.py2
-rw-r--r--release/scripts/startup/bl_ui/space_node.py2
-rw-r--r--release/scripts/startup/bl_ui/space_text.py60
-rw-r--r--release/scripts/startup/bl_ui/space_userpref.py8
-rw-r--r--release/scripts/startup/bl_ui/space_userpref_keymap.py7
-rw-r--r--release/scripts/startup/bl_ui/space_view3d.py43
-rw-r--r--release/scripts/startup/bl_ui/space_view3d_toolbar.py1
-rw-r--r--release/scripts/templates/addon_add_object.py2
-rw-r--r--release/scripts/templates/batch_export.py2
-rw-r--r--release/scripts/templates/ui_menu.py49
-rw-r--r--release/scripts/templates/ui_menu_simple.py26
-rw-r--r--release/scripts/templates/ui_panel_simple.py (renamed from release/scripts/templates/panel_simple.py)7
-rw-r--r--source/blender/blenkernel/BKE_blender.h2
-rw-r--r--source/blender/blenkernel/BKE_curve.h1
-rw-r--r--source/blender/blenkernel/BKE_global.h5
-rw-r--r--source/blender/blenkernel/BKE_material.h2
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c4
-rw-r--r--source/blender/blenkernel/intern/cdderivedmesh.c2
-rw-r--r--source/blender/blenkernel/intern/curve.c70
-rw-r--r--source/blender/blenkernel/intern/customdata.c1
-rw-r--r--source/blender/blenkernel/intern/ipo.c8
-rw-r--r--source/blender/blenkernel/intern/key.c8
-rw-r--r--source/blender/blenkernel/intern/material.c85
-rw-r--r--source/blender/blenkernel/intern/mesh.c4
-rw-r--r--source/blender/blenkernel/intern/multires.c18
-rw-r--r--source/blender/blenkernel/intern/seqeffects.c2
-rw-r--r--source/blender/blenkernel/intern/text.c10
-rw-r--r--source/blender/blenlib/intern/BLI_args.c6
-rw-r--r--source/blender/blenlib/intern/pbvh.c83
-rw-r--r--source/blender/blenloader/intern/readfile.c5
-rw-r--r--source/blender/collada/MaterialExporter.cpp32
-rw-r--r--source/blender/collada/MaterialExporter.h3
-rw-r--r--source/blender/editors/armature/editarmature.c2
-rw-r--r--source/blender/editors/curve/editcurve.c16
-rw-r--r--source/blender/editors/gpencil/gpencil_paint.c12
-rw-r--r--source/blender/editors/include/BIF_glutil.h2
-rw-r--r--source/blender/editors/include/ED_transform.h1
-rw-r--r--source/blender/editors/interface/interface_anim.c24
-rw-r--r--source/blender/editors/interface/interface_handlers.c11
-rw-r--r--source/blender/editors/interface/interface_layout.c12
-rw-r--r--source/blender/editors/interface/interface_panel.c4
-rw-r--r--source/blender/editors/interface/interface_regions.c11
-rw-r--r--source/blender/editors/interface/interface_templates.c3
-rw-r--r--source/blender/editors/interface/resources.c22
-rw-r--r--source/blender/editors/object/object_add.c4
-rw-r--r--source/blender/editors/object/object_relations.c6
-rw-r--r--source/blender/editors/screen/glutil.c38
-rw-r--r--source/blender/editors/screen/screen_ops.c2
-rw-r--r--source/blender/editors/sculpt_paint/paint_image.c26
-rw-r--r--source/blender/editors/sculpt_paint/paint_stroke.c7
-rw-r--r--source/blender/editors/space_image/image_intern.h1
-rw-r--r--source/blender/editors/space_image/image_ops.c50
-rw-r--r--source/blender/editors/space_image/space_image.c4
-rw-r--r--source/blender/editors/space_node/node_draw.c13
-rw-r--r--source/blender/editors/space_node/node_edit.c8
-rw-r--r--source/blender/editors/space_sequencer/sequencer_add.c27
-rw-r--r--source/blender/editors/space_sequencer/sequencer_draw.c19
-rw-r--r--source/blender/editors/space_text/text_ops.c21
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c102
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c631
-rw-r--r--source/blender/editors/space_view3d/view3d_fly.c480
-rw-r--r--source/blender/editors/space_view3d/view3d_header.c3
-rw-r--r--source/blender/editors/space_view3d/view3d_intern.h5
-rw-r--r--source/blender/editors/space_view3d/view3d_ops.c24
-rw-r--r--source/blender/editors/space_view3d/view3d_select.c6
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c2
-rw-r--r--source/blender/editors/transform/transform.c143
-rw-r--r--source/blender/editors/transform/transform.h2
-rw-r--r--source/blender/editors/transform/transform_generics.c19
-rw-r--r--source/blender/editors/transform/transform_ops.c19
-rw-r--r--source/blender/editors/transform/transform_snap.c28
-rw-r--r--source/blender/editors/util/undo.c8
-rw-r--r--source/blender/editors/uvedit/uvedit_ops.c4
-rw-r--r--source/blender/gpu/intern/gpu_material.c9
-rw-r--r--source/blender/makesdna/DNA_modifier_types.h1
-rw-r--r--source/blender/makesdna/DNA_scene_types.h2
-rw-r--r--source/blender/makesdna/DNA_userdef_types.h32
-rw-r--r--source/blender/makesdna/DNA_view3d_types.h13
-rw-r--r--source/blender/makesrna/intern/rna_ID.c4
-rw-r--r--source/blender/makesrna/intern/rna_access.c10
-rw-r--r--source/blender/makesrna/intern/rna_action.c5
-rw-r--r--source/blender/makesrna/intern/rna_modifier.c5
-rw-r--r--source/blender/makesrna/intern/rna_object_api.c2
-rw-r--r--source/blender/makesrna/intern/rna_scene.c8
-rw-r--r--source/blender/makesrna/intern/rna_userdef.c33
-rw-r--r--source/blender/makesrna/intern/rna_wm.c90
-rw-r--r--source/blender/makesrna/intern/rna_wm_api.c2
-rw-r--r--source/blender/modifiers/intern/MOD_uvproject.c2
-rw-r--r--source/blender/python/intern/bpy_props.c26
-rw-r--r--source/blender/python/intern/bpy_rna.c14
-rw-r--r--source/blender/python/mathutils/mathutils.h2
-rw-r--r--source/blender/python/mathutils/mathutils_Matrix.c14
-rw-r--r--source/blender/python/mathutils/mathutils_Quaternion.c26
-rw-r--r--source/blender/python/mathutils/mathutils_Vector.c80
-rw-r--r--source/blender/render/intern/source/convertblender.c8
-rw-r--r--source/blender/render/intern/source/rendercore.c2
-rw-r--r--source/blender/windowmanager/WM_api.h1
-rw-r--r--source/blender/windowmanager/WM_types.h20
-rw-r--r--source/blender/windowmanager/intern/wm.c6
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c84
-rw-r--r--source/blender/windowmanager/intern/wm_init_exit.c5
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c69
-rw-r--r--source/blender/windowmanager/intern/wm_window.c4
-rw-r--r--source/blender/windowmanager/wm_event_types.h56
-rw-r--r--source/blenderplayer/bad_level_call_stubs/stubs.c1
-rw-r--r--source/creator/creator.c7
-rw-r--r--source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp4
-rw-r--r--source/gameengine/Ketsji/KX_KetsjiEngine.cpp2
-rw-r--r--source/gameengine/Ketsji/KX_PyConstraintBinding.cpp285
-rw-r--r--source/tests/CMakeLists.txt12
-rw-r--r--source/tests/check_deprecated.py13
204 files changed, 5272 insertions, 2360 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d4489a8c76b..a0a0359d8d7 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -179,6 +179,7 @@ option(WITH_LZO "Enable fast LZO compression (used for pointcache)" ON
option(WITH_LZMA "Enable best LZMA compression, (used for pointcache)" ON)
# Misc
+option(WITH_INPUT_NDOF "Enable NDOF input devices (SpaceNavigator and friends)" ON)
option(WITH_RAYOPTIMIZATION "Enable use of SIMD (SSE) optimizations for the raytracer" ON)
if(UNIX AND NOT APPLE)
option(WITH_INSTALL_PORTABLE "Install redistributeable runtime, otherwise install into CMAKE_INSTALL_PREFIX" ON)
@@ -452,6 +453,19 @@ if(UNIX AND NOT APPLE)
endif()
endif()
+ if (WITH_INPUT_NDOF)
+ find_package(Spacenav)
+ if(NOT SPACENAV_FOUND)
+ set(WITH_INPUT_NDOF OFF)
+ endif()
+
+ # use generic names within blenders buildsystem.
+ if(SPACENAV_FOUND)
+ set(NDOF_INCLUDE_DIRS ${SPACENAV_INCLUDE_DIRS})
+ set(NDOF_LIBRARIES ${SPACENAV_LIBRARIES})
+ endif()
+ endif()
+
# OpenSuse needs lutil, ArchLinux not, for now keep, can avoid by using --as-needed
set(PLATFORM_LINKLIBS "-lutil -lc -lm -lpthread -lstdc++")
@@ -896,28 +910,15 @@ elseif(APPLE)
endif()
if(WITH_PYTHON)
- set(PYTHON_VERSION 3.2)
- if(PYTHON_VERSION MATCHES 3.2)
- # we use precompiled libraries for py 3.2 and up by default
+ # we use precompiled libraries for py 3.2 and up by default
- # normally cached but not since we include them with blender
- set(PYTHON_INCLUDE_DIR "${LIBDIR}/python/include/python${PYTHON_VERSION}")
- # set(PYTHON_BINARY "${LIBDIR}/python/bin/python${PYTHON_VERSION}") # not used yet
- set(PYTHON_LIBRARY python${PYTHON_VERSION})
- set(PYTHON_LIBPATH "${LIBDIR}/python/lib/python${PYTHON_VERSION}")
- # set(PYTHON_LINKFLAGS "-u _PyMac_Error") # won't build with this enabled
- else()
- # otherwise, use custom system framework
- # *not used but maintained incase some dev wants to*
-
- set(PYTHON "/System/Library/Frameworks/Python.framework/Versions/" CACHE PATH)
- set(PYTHON_INCLUDE_DIR "${PYTHON}${PYTHON_VERSION}/include/python${PYTHON_VERSION}" CACHE PATH)
- # set(PYTHON_BINARY ${PYTHON}${PYTHON_VERSION}/bin/python${PYTHON_VERSION}) # not used yet
- set(PYTHON_LIBRARY "" CACHE FILEPATH)
- set(PYTHON_LIBPATH "${PYTHON}${PYTHON_VERSION}/lib/python${PYTHON_VERSION}/config" CACHE PATH)
- set(PYTHON_LINKFLAGS "-u _PyMac_Error -framework System -framework Python" CACHE STRING)
- unset(PYTHON)
- endif()
+ # normally cached but not since we include them with blender
+ set(PYTHON_VERSION 3.2)
+ set(PYTHON_INCLUDE_DIR "${LIBDIR}/python/include/python${PYTHON_VERSION}")
+ # set(PYTHON_BINARY "${LIBDIR}/python/bin/python${PYTHON_VERSION}") # not used yet
+ set(PYTHON_LIBRARY python${PYTHON_VERSION})
+ set(PYTHON_LIBPATH "${LIBDIR}/python/lib/python${PYTHON_VERSION}")
+ # set(PYTHON_LINKFLAGS "-u _PyMac_Error") # won't build with this enabled
# uncached vars
set(PYTHON_INCLUDE_DIRS "${PYTHON_INCLUDE_DIR}")
@@ -972,7 +973,17 @@ elseif(APPLE)
set(SAMPLERATE_LIBPATH ${SAMPLERATE}/lib)
endif()
- set(PLATFORM_LINKLIBS stdc++ SystemStubs)
+ find_library(SYSTEMSTUBS_LIBRARY
+ NAMES
+ SystemStubs
+ PATHS
+ )
+ mark_as_advanced(SYSTEMSTUBS_LIBRARY)
+ if(SYSTEMSTUBS_LIBRARY)
+ set(PLATFORM_LINKLIBS stdc++ SystemStubs)
+ else()
+ set(PLATFORM_LINKLIBS stdc++)
+ endif()
if(WITH_COCOA)
set(PLATFORM_CFLAGS "-pipe -funsigned-char -DGHOST_COCOA")
@@ -987,9 +998,24 @@ elseif(APPLE)
elseif(WITH_CODEC_QUICKTIME)
set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -framework QuickTime")
endif()
+
+ # XXX - SOME MAC DEV PLEASE TEST WITH THE SDK INSTALLED!
+ # ALSO SHOULD BE MOVED INTO OWN MODULE WHEN FUNCTIONAL
+ if(WITH_INPUT_NDOF)
+ # This thread it *should* work and check the framework - campbell
+ # http://www.cmake.org/pipermail/cmake/2005-December/007740.html
+ find_library(3D_CONNEXION_CLIENT_LIBRARY
+ NAMES 3DconnexionClient
+ )
+ if(NOT 3D_CONNEXION_CLIENT_LIBRARY)
+ set(WITH_INPUT_NDOF OFF)
+ endif()
+ endif()
+
else()
set(PLATFORM_CFLAGS "-pipe -funsigned-char")
set(PLATFORM_LINKFLAGS "-fexceptions -framework CoreServices -framework Foundation -framework IOKit -framework AppKit -framework Carbon -framework AGL -framework AudioUnit -framework AudioToolbox -framework CoreAudio -framework QuickTime")
+ set(WITH_INPUT_NDOF OFF) # unsupported
endif()
if(WITH_OPENCOLLADA)
@@ -1029,6 +1055,10 @@ elseif(APPLE)
set(TIFF_LIBPATH ${TIFF}/lib)
endif()
+ if (WITH_INPUT_NDOF)
+ # linker needs "-weak_framework 3DconnexionClient"
+ endif()
+
set(EXETYPE MACOSX_BUNDLE)
set(CMAKE_C_FLAGS_DEBUG "-fno-strict-aliasing -g")
@@ -1054,20 +1084,34 @@ if(APPLE OR WIN32)
endif()
endif()
+# See TEST_SSE_SUPPORT() for how this is defined.
+
if(WITH_RAYOPTIMIZATION)
if(CMAKE_COMPILER_IS_GNUCC)
- if(SUPPORT_SSE_BUILD)
- set(PLATFORM_CFLAGS " -msse ${PLATFORM_CFLAGS}")
- add_definitions(-D__SSE__ -D__MMX__)
- endif()
- if(SUPPORT_SSE2_BUILD)
- set(PLATFORM_CFLAGS " -msse2 ${PLATFORM_CFLAGS}")
- add_definitions(-D__SSE2__)
- if(NOT SUPPORT_SSE_BUILD) # dont double up
- add_definitions(-D__MMX__)
- endif()
+ set(_sse "-msse")
+ set(_sse2 "-msse2")
+ elseif(MSVC)
+ set(_sse "/arch:SSE")
+ set(_sse2 "/arch:SSE2")
+ else()
+ message(WARNING "SSE flags for this compiler not known")
+ set(_sse)
+ set(_sse2)
+ endif()
+
+ if(SUPPORT_SSE_BUILD)
+ set(PLATFORM_CFLAGS " ${_sse} ${PLATFORM_CFLAGS}")
+ add_definitions(-D__SSE__ -D__MMX__)
+ endif()
+ if(SUPPORT_SSE2_BUILD)
+ set(PLATFORM_CFLAGS " ${_sse2} ${PLATFORM_CFLAGS}")
+ add_definitions(-D__SSE2__)
+ if(NOT SUPPORT_SSE_BUILD) # dont double up
+ add_definitions(-D__MMX__)
endif()
endif()
+ unset(_sse)
+ unset(_sse2)
endif()
if(WITH_IMAGE_OPENJPEG)
@@ -1306,6 +1350,7 @@ if(FIRST_RUN)
info_cfg_option(WITH_OPENCOLLADA)
info_cfg_option(WITH_FFTW3)
info_cfg_option(WITH_INTERNATIONAL)
+ info_cfg_option(WITH_INPUT_NDOF)
info_cfg_text("Compiler Options:")
info_cfg_option(WITH_BUILDINFO)
diff --git a/SConstruct b/SConstruct
index 053f414c954..529f6daeef1 100644
--- a/SConstruct
+++ b/SConstruct
@@ -111,6 +111,11 @@ btools.print_targets(B.targets, B.bc)
# handling cmd line arguments & config file
+# bitness stuff
+tempbitness = int(B.arguments.get('BF_BITNESS', bitness)) # default to bitness found as per starting python
+if tempbitness in (32, 64): # only set if 32 or 64 has been given
+ bitness = int(tempbitness)
+
# first check cmdline for toolset and we create env to work on
quickie = B.arguments.get('BF_QUICK', None)
quickdebug = B.arguments.get('BF_QUICKDEBUG', None)
@@ -241,6 +246,7 @@ if 'blenderlite' in B.targets:
target_env_defs['BF_BUILDINFO'] = False
target_env_defs['BF_NO_ELBEEM'] = True
target_env_defs['WITH_BF_PYTHON'] = False
+ target_env_defs['WITH_BF_3DMOUSE'] = False
# Merge blenderlite, let command line to override
for k,v in target_env_defs.iteritems():
@@ -658,11 +664,7 @@ if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'win64-vc', 'linuxcross'):
dllsources.append('${LCGDIR}/sndfile/lib/libsndfile-1.dll')
if env['WITH_BF_FFMPEG']:
- dllsources += ['${BF_FFMPEG_LIBPATH}/avcodec-52.dll',
- '${BF_FFMPEG_LIBPATH}/avformat-52.dll',
- '${BF_FFMPEG_LIBPATH}/avdevice-52.dll',
- '${BF_FFMPEG_LIBPATH}/avutil-50.dll',
- '${BF_FFMPEG_LIBPATH}/swscale-0.dll']
+ dllsources += env['BF_FFMPEG_DLL'].split()
# Since the thumb handler is loaded by Explorer, architecture is
# strict: the x86 build fails on x64 Windows. We need to ship
diff --git a/build_files/buildbot/config/user-config-i686.py b/build_files/buildbot/config/user-config-i686.py
index 1ad6c5d22fe..e09fecede59 100644
--- a/build_files/buildbot/config/user-config-i686.py
+++ b/build_files/buildbot/config/user-config-i686.py
@@ -22,7 +22,7 @@ BF_EXPAT_LIB = ''
WITH_BF_FFMPEG = True
WITH_BF_STATICFFMPEG = True
-BF_FFMPEG = '/home/sources/staticlibs/ffmpeg'
+BF_FFMPEG = '/home/sources/staticlibs/ffmpeg-0.8'
BF_FFMPEG_LIBPATH = '${BF_FFMPEG}/lib32'
BF_FFMPEG_LIB_STATIC = '${BF_FFMPEG_LIBPATH}/libavformat.a ${BF_FFMPEG_LIBPATH}/libswscale.a ' + \
'${BF_FFMPEG_LIBPATH}/libavcodec.a ${BF_FFMPEG_LIBPATH}/libavdevice.a ${BF_FFMPEG_LIBPATH}/libavutil.a ' + \
@@ -81,6 +81,12 @@ WITH_BF_STATICJEMALLOC = True
BF_JEMALLOC = '/home/sources/staticlibs/jemalloc'
BF_JEMALLOC_LIBPATH = '${BF_JEMALLOC}/lib32'
+# Use 3d mouse library
+WITH_BF_3DMOUSE = True
+WITH_BF_STATIC3DMOUSE = True
+BF_3DMOUSE = '/home/sources/staticlibs/spnav'
+BF_3DMOUSE_LIBPATH = '${BF_3DMOUSE}/lib32'
+
# Compilation and optimization
BF_DEBUG = False
REL_CFLAGS = ['-O2']
diff --git a/build_files/buildbot/config/user-config-player-i686.py b/build_files/buildbot/config/user-config-player-i686.py
index 241f5a79983..279f2d66804 100644
--- a/build_files/buildbot/config/user-config-player-i686.py
+++ b/build_files/buildbot/config/user-config-player-i686.py
@@ -13,7 +13,18 @@ WITH_BF_STATICPYTHON = True
WITH_BF_COLLADA = False
# FFMPEG configuration
-WITH_BF_FFMPEG = False
+WITH_BF_FFMPEG = True
+WITH_BF_STATICFFMPEG = True
+
+BF_FFMPEG = '/home/sources/staticlibs/ffmpeg-0.8'
+BF_FFMPEG_LIBPATH = '${BF_FFMPEG}/lib32'
+BF_FFMPEG_LIB_STATIC = '${BF_FFMPEG_LIBPATH}/libavformat.a ${BF_FFMPEG_LIBPATH}/libswscale.a ' + \
+ '${BF_FFMPEG_LIBPATH}/libavcodec.a ${BF_FFMPEG_LIBPATH}/libavdevice.a ${BF_FFMPEG_LIBPATH}/libavutil.a ' + \
+ '${BF_FFMPEG_LIBPATH}/libxvidcore.a ${BF_FFMPEG_LIBPATH}/libx264.a ${BF_FFMPEG_LIBPATH}/libmp3lame.a ' + \
+ '${BF_FFMPEG_LIBPATH}/libvpx.a ${BF_FFMPEG_LIBPATH}/libvorbis.a ${BF_FFMPEG_LIBPATH}/libogg.a ' + \
+ '${BF_FFMPEG_LIBPATH}/libvorbisenc.a ${BF_FFMPEG_LIBPATH}/libtheora.a ' + \
+ '${BF_FFMPEG_LIBPATH}/libschroedinger-1.0.a ${BF_FFMPEG_LIBPATH}/liborc-0.4.a ${BF_FFMPEG_LIBPATH}/libdirac_encoder.a ' + \
+ '${BF_FFMPEG_LIBPATH}/libfaad.a'
# Don't depend on system's libstdc++
WITH_BF_STATICCXX = True
@@ -65,6 +76,12 @@ WITH_BF_STATICJEMALLOC = True
BF_JEMALLOC = '/home/sources/staticlibs/jemalloc'
BF_JEMALLOC_LIBPATH = '${BF_JEMALLOC}/lib32'
+# Use 3d mouse library
+WITH_BF_3DMOUSE = True
+WITH_BF_STATIC3DMOUSE = True
+BF_3DMOUSE = '/home/sources/staticlibs/spnav'
+BF_3DMOUSE_LIBPATH = '${BF_3DMOUSE}/lib32'
+
# Compilation and optimization
BF_DEBUG = False
REL_CFLAGS = ['-O2']
diff --git a/build_files/buildbot/config/user-config-player-x86_64.py b/build_files/buildbot/config/user-config-player-x86_64.py
index d51894b26cf..d1914338510 100644
--- a/build_files/buildbot/config/user-config-player-x86_64.py
+++ b/build_files/buildbot/config/user-config-player-x86_64.py
@@ -13,7 +13,18 @@ WITH_BF_STATICPYTHON = True
WITH_BF_COLLADA = False
# FFMPEG configuration
-WITH_BF_FFMPEG = False
+WITH_BF_FFMPEG = True
+WITH_BF_STATICFFMPEG = True
+
+BF_FFMPEG = '/home/sources/staticlibs/ffmpeg-0.8'
+BF_FFMPEG_LIBPATH = '${BF_FFMPEG}/lib64'
+BF_FFMPEG_LIB_STATIC = '${BF_FFMPEG_LIBPATH}/libavformat.a ${BF_FFMPEG_LIBPATH}/libswscale.a ' + \
+ '${BF_FFMPEG_LIBPATH}/libavcodec.a ${BF_FFMPEG_LIBPATH}/libavdevice.a ${BF_FFMPEG_LIBPATH}/libavutil.a ' + \
+ '${BF_FFMPEG_LIBPATH}/libxvidcore.a ${BF_FFMPEG_LIBPATH}/libx264.a ${BF_FFMPEG_LIBPATH}/libmp3lame.a ' + \
+ '${BF_FFMPEG_LIBPATH}/libvpx.a ${BF_FFMPEG_LIBPATH}/libvorbis.a ${BF_FFMPEG_LIBPATH}/libogg.a ' + \
+ '${BF_FFMPEG_LIBPATH}/libvorbisenc.a ${BF_FFMPEG_LIBPATH}/libtheora.a ' + \
+ '${BF_FFMPEG_LIBPATH}/libschroedinger-1.0.a ${BF_FFMPEG_LIBPATH}/liborc-0.4.a ${BF_FFMPEG_LIBPATH}/libdirac_encoder.a ' + \
+ '${BF_FFMPEG_LIBPATH}/libfaad.a'
# Don't depend on system's libstdc++
WITH_BF_STATICCXX = True
@@ -65,6 +76,12 @@ WITH_BF_STATICJEMALLOC = True
BF_JEMALLOC = '/home/sources/staticlibs/jemalloc'
BF_JEMALLOC_LIBPATH = '${BF_JEMALLOC}/lib64'
+# Use 3d mouse library
+WITH_BF_3DMOUSE = True
+WITH_BF_STATIC3DMOUSE = True
+BF_3DMOUSE = '/home/sources/staticlibs/spnav'
+BF_3DMOUSE_LIBPATH = '${BF_3DMOUSE}/lib64'
+
# Compilation and optimization
BF_DEBUG = False
REL_CFLAGS = ['-O2']
diff --git a/build_files/buildbot/config/user-config-x86_64.py b/build_files/buildbot/config/user-config-x86_64.py
index 3eaadd99d45..bdba8892bf8 100644
--- a/build_files/buildbot/config/user-config-x86_64.py
+++ b/build_files/buildbot/config/user-config-x86_64.py
@@ -22,7 +22,7 @@ BF_EXPAT_LIB = ''
WITH_BF_FFMPEG = True
WITH_BF_STATICFFMPEG = True
-BF_FFMPEG = '/home/sources/staticlibs/ffmpeg'
+BF_FFMPEG = '/home/sources/staticlibs/ffmpeg-0.8'
BF_FFMPEG_LIBPATH = '${BF_FFMPEG}/lib64'
BF_FFMPEG_LIB_STATIC = '${BF_FFMPEG_LIBPATH}/libavformat.a ${BF_FFMPEG_LIBPATH}/libswscale.a ' + \
'${BF_FFMPEG_LIBPATH}/libavcodec.a ${BF_FFMPEG_LIBPATH}/libavdevice.a ${BF_FFMPEG_LIBPATH}/libavutil.a ' + \
@@ -81,6 +81,12 @@ WITH_BF_STATICJEMALLOC = True
BF_JEMALLOC = '/home/sources/staticlibs/jemalloc'
BF_JEMALLOC_LIBPATH = '${BF_JEMALLOC}/lib64'
+# Use 3d mouse library
+WITH_BF_3DMOUSE = True
+WITH_BF_STATIC3DMOUSE = True
+BF_3DMOUSE = '/home/sources/staticlibs/spnav'
+BF_3DMOUSE_LIBPATH = '${BF_3DMOUSE}/lib64'
+
# Compilation and optimization
BF_DEBUG = False
REL_CFLAGS = ['-O2']
diff --git a/build_files/buildbot/master.cfg b/build_files/buildbot/master.cfg
index fd712f1b832..1e70ec5e13e 100644
--- a/build_files/buildbot/master.cfg
+++ b/build_files/buildbot/master.cfg
@@ -116,6 +116,7 @@ add_builder(c, 'linux_x86_64_scons', '', generic_builder)
add_builder(c, 'salad_linux_x86_64_scons', '', generic_builder, 'soc-2011-salad')
add_builder(c, 'win32_scons', 'windows', generic_builder)
add_builder(c, 'salad_win32_scons', 'windows', generic_builder, 'soc-2011-salad')
+add_builder(c, 'win64_scons', 'windows', generic_builder)
#add_builder(c, 'freebsd_i386_cmake', '', generic_builder)
#add_builder(c, 'freebsd_x86_64_cmake', '', generic_builder)
diff --git a/build_files/buildbot/slave_compile.py b/build_files/buildbot/slave_compile.py
index e74d889c243..9dd39ccd308 100644
--- a/build_files/buildbot/slave_compile.py
+++ b/build_files/buildbot/slave_compile.py
@@ -108,5 +108,33 @@ else:
sys.exit(0)
else:
+ bitness = '32'
+ # Switch to new FFmpeg library
+ if builder.find('win') != -1:
+ if builder.find('win32') != -1:
+ LCGDIR = '#../lib/windows'
+ elif builder.find('win64') != -1:
+ LCGDIR = '#../lib/win64'
+ bitness = '64'
+
+ all_ffmpeg_libs = ['avcodec-53',
+ 'avdevice-53',
+ 'avformat-53',
+ 'avutil-51',
+ 'swscale-2']
+
+ ffmpeg_lib = []
+ ffmpeg_dll = []
+
+ for lib in all_ffmpeg_libs:
+ ffmpeg_lib.append(lib + '.lib')
+ ffmpeg_dll.append('${BF_FFMPEG_LIBPATH}/' + lib + '.dll')
+
+ scons_options.append('BF_FFMPEG=' + LCGDIR + '/ffmpeg-0.8')
+ scons_options.append('BF_FFMPEG_LIB=' + (' '.join(ffmpeg_lib)))
+ scons_options.append('BF_FFMPEG_DLL=' + (' '.join(ffmpeg_dll)))
+
+ scons_options.append('BF_BITNESS='+bitness)
+
retcode = subprocess.call(['python', 'scons/scons.py'] + scons_options)
sys.exit(retcode)
diff --git a/build_files/buildbot/slave_pack.py b/build_files/buildbot/slave_pack.py
index 4c19b723fc8..e779b10bd2a 100644
--- a/build_files/buildbot/slave_pack.py
+++ b/build_files/buildbot/slave_pack.py
@@ -72,6 +72,34 @@ if builder.find('scons') != -1:
retcode = subprocess.call(['python', 'scons/scons.py'] + scons_options)
sys.exit(retcode)
else:
+ bitness = '32'
+ # Switch to new FFmpeg library
+ if builder.find('win') != -1:
+ if builder.find('win32') != -1:
+ LCGDIR = '#../lib/windows'
+ elif builder.find('win64') != -1:
+ LCGDIR = '#../lib/win64'
+ bitness = '64'
+
+ all_ffmpeg_libs = ['avcodec-53',
+ 'avdevice-53',
+ 'avformat-53',
+ 'avutil-51',
+ 'swscale-2']
+
+ ffmpeg_lib = []
+ ffmpeg_dll = []
+
+ for lib in all_ffmpeg_libs:
+ ffmpeg_lib.append(lib + '.lib')
+ ffmpeg_dll.append('${BF_FFMPEG_LIBPATH}/' + lib + '.dll')
+
+ scons_options.append('BF_FFMPEG=' + LCGDIR + '/ffmpeg-0.8')
+ scons_options.append('BF_FFMPEG_LIB=' + (' '.join(ffmpeg_lib)))
+ scons_options.append('BF_FFMPEG_DLL=' + (' '.join(ffmpeg_dll)))
+
+ scons_options.append('BF_BITNESS='+bitness)
+
retcode = subprocess.call(['python', 'scons/scons.py'] + scons_options)
sys.exit(retcode)
diff --git a/build_files/cmake/Modules/FindSpacenav.cmake b/build_files/cmake/Modules/FindSpacenav.cmake
new file mode 100644
index 00000000000..206f3611ed6
--- /dev/null
+++ b/build_files/cmake/Modules/FindSpacenav.cmake
@@ -0,0 +1,70 @@
+# - Find Spacenav library
+# Find the native Spacenav includes and library
+# This module defines
+# SPACENAV_INCLUDE_DIRS, where to find spnav.h, Set when
+# SPACENAV_INCLUDE_DIR is found.
+# SPACENAV_LIBRARIES, libraries to link against to use Spacenav.
+# SPACENAV_ROOT_DIR, The base directory to search for Spacenav.
+# This can also be an environment variable.
+# SPACENAV_FOUND, If false, do not try to use Spacenav.
+#
+# also defined, but not for general use are
+# SPACENAV_LIBRARY, where to find the Spacenav library.
+
+#=============================================================================
+# Copyright 2011 Blender Foundation.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+
+# If SPACENAV_ROOT_DIR was defined in the environment, use it.
+IF(NOT SPACENAV_ROOT_DIR AND NOT $ENV{SPACENAV_ROOT_DIR} STREQUAL "")
+ SET(SPACENAV_ROOT_DIR $ENV{SPACENAV_ROOT_DIR})
+ENDIF()
+
+SET(_spacenav_SEARCH_DIRS
+ ${SPACENAV_ROOT_DIR}
+ /usr/local
+ /sw # Fink
+ /opt/local # DarwinPorts
+ /opt/csw # Blastwave
+)
+
+FIND_PATH(SPACENAV_INCLUDE_DIR
+ NAMES
+ spnav.h
+ HINTS
+ ${_spacenav_SEARCH_DIRS}
+ PATH_SUFFIXES
+ include
+)
+
+FIND_LIBRARY(SPACENAV_LIBRARY
+ NAMES
+ spnav
+ HINTS
+ ${_spacenav_SEARCH_DIRS}
+ PATH_SUFFIXES
+ lib64 lib
+ )
+
+# handle the QUIETLY and REQUIRED arguments and set SPACENAV_FOUND to TRUE if
+# all listed variables are TRUE
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(Spacenav DEFAULT_MSG
+ SPACENAV_LIBRARY SPACENAV_INCLUDE_DIR)
+
+IF(SPACENAV_FOUND)
+ SET(SPACENAV_LIBRARIES ${SPACENAV_LIBRARY})
+ SET(SPACENAV_INCLUDE_DIRS ${SPACENAV_INCLUDE_DIR})
+ENDIF(SPACENAV_FOUND)
+
+MARK_AS_ADVANCED(
+ SPACENAV_INCLUDE_DIR
+ SPACENAV_LIBRARY
+)
diff --git a/build_files/cmake/cmake_consistency_check.py b/build_files/cmake/cmake_consistency_check.py
index 4b35e34a5cd..880cb582f1e 100755
--- a/build_files/cmake/cmake_consistency_check.py
+++ b/build_files/cmake/cmake_consistency_check.py
@@ -39,12 +39,12 @@ def replace_line(f, i, text, keep_indent=True):
file_handle = open(f, 'r')
data = file_handle.readlines()
file_handle.close()
-
+
l = data[i]
ws = l[:len(l) - len(l.lstrip())]
-
+
data[i] = "%s%s\n" % (ws, text)
-
+
file_handle = open(f, 'w')
file_handle.writelines(data)
file_handle.close()
@@ -182,13 +182,13 @@ def cmake_get_src(f):
if new_path_rel != l:
print("overly relative path:\n %s:%d\n %s\n %s" % (f, i, l, new_path_rel))
-
+
## Save time. just replace the line
# replace_line(f, i - 1, new_path_rel)
-
+
else:
raise Exception("non existant include %s:%d -> %s" % (f, i, new_file))
-
+
# print(new_file)
global_h.update(set(sources_h))
@@ -206,7 +206,7 @@ def cmake_get_src(f):
if ff not in sources_c:
print(" missing: " + ff)
'''
-
+
# reset
sources_h[:] = []
sources_c[:] = []
diff --git a/build_files/cmake/cmake_netbeans_project.py b/build_files/cmake/cmake_netbeans_project.py
index 6afca8f3b6a..02dfec06c0b 100755
--- a/build_files/cmake/cmake_netbeans_project.py
+++ b/build_files/cmake/cmake_netbeans_project.py
@@ -30,7 +30,18 @@ Example linux usage
Windows not supported so far
"""
-from project_info import *
+from project_info import (SIMPLE_PROJECTFILE,
+ SOURCE_DIR,
+ CMAKE_DIR,
+ PROJECT_DIR,
+ source_list,
+ is_project_file,
+ is_c_header,
+ # is_py,
+ cmake_advanced_info,
+ cmake_compiler_defines,
+ )
+
import os
from os.path import join, dirname, normpath, relpath, exists
diff --git a/build_files/cmake/cmake_qtcreator_project.py b/build_files/cmake/cmake_qtcreator_project.py
index 3de15567727..2a2774c9944 100755
--- a/build_files/cmake/cmake_qtcreator_project.py
+++ b/build_files/cmake/cmake_qtcreator_project.py
@@ -31,7 +31,17 @@ example linux usage
python .~/blenderSVN/blender/build_files/cmake/cmake_qtcreator_project.py ~/blenderSVN/cmake
"""
-from project_info import *
+from project_info import (SIMPLE_PROJECTFILE,
+ SOURCE_DIR,
+ # CMAKE_DIR,
+ PROJECT_DIR,
+ source_list,
+ is_project_file,
+ is_c_header,
+ is_py,
+ cmake_advanced_info,
+ cmake_compiler_defines,
+ )
import os
import sys
diff --git a/build_files/cmake/macros.cmake b/build_files/cmake/macros.cmake
index 34301458a06..ed200abd419 100644
--- a/build_files/cmake/macros.cmake
+++ b/build_files/cmake/macros.cmake
@@ -314,6 +314,10 @@ macro(setup_liblinks
if(WITH_MEM_JEMALLOC)
target_link_libraries(${target} ${JEMALLOC_LIBRARIES})
endif()
+ if(WITH_INPUT_NDOF)
+ target_link_libraries(${target} ${NDOF_LIBRARIES})
+ endif()
+
if(WIN32 AND NOT UNIX)
target_link_libraries(${target} ${PTHREADS_LIBRARIES})
endif()
diff --git a/build_files/scons/config/darwin-config.py b/build_files/scons/config/darwin-config.py
index 0c51476a6d0..00b0c6ebf00 100644
--- a/build_files/scons/config/darwin-config.py
+++ b/build_files/scons/config/darwin-config.py
@@ -264,7 +264,9 @@ if MACOSX_ARCHITECTURE == 'i386':
BF_RAYOPTIMIZATION_SSE_FLAGS = ['-msse']
elif MACOSX_ARCHITECTURE == 'x86_64':
BF_RAYOPTIMIZATION_SSE_FLAGS = ['-msse','-msse2']
-
+
+# SpaceNavigator and related 3D mice
+WITH_BF_3DMOUSE = False
#############################################################################
################### various compile settings and flags ##################
@@ -294,6 +296,9 @@ if WITH_BF_QUICKTIME == True:
else:
PLATFORM_LINKFLAGS = PLATFORM_LINKFLAGS+['-framework','QuickTime']
+if WITH_BF_3DMOUSE:
+ PLATFORM_LINKFLAGS = PLATFORM_LINKFLAGS + ['-weak_framework','3DconnexionClient']
+
#note to build succesfully on 10.3.9 SDK you need to patch 10.3.9 by adding the SystemStubs.a lib from 10.4
LLIBS = ['stdc++', 'SystemStubs']
diff --git a/build_files/scons/config/linux2-config.py b/build_files/scons/config/linux2-config.py
index 328cd4cdb28..d8e227cfb21 100644
--- a/build_files/scons/config/linux2-config.py
+++ b/build_files/scons/config/linux2-config.py
@@ -192,6 +192,14 @@ WITH_BF_OPENMP = True
WITH_BF_RAYOPTIMIZATION = True
BF_RAYOPTIMIZATION_SSE_FLAGS = ['-msse','-pthread']
+#SpaceNavigator and friends
+WITH_BF_3DMOUSE = True
+BF_3DMOUSE = '/usr'
+BF_3DMOUSE_INC = '${BF_3DMOUSE}/include'
+BF_3DMOUSE_LIBPATH = '${BF_3DMOUSE}/lib'
+BF_3DMOUSE_LIB = 'spnav'
+BF_3DMOUSE_LIB_STATIC = '${BF_3DMOUSE_LIBPATH}/libspnav.a'
+
##
CC = 'gcc'
CXX = 'g++'
diff --git a/build_files/scons/config/win32-vc-config.py b/build_files/scons/config/win32-vc-config.py
index 89b246cb39f..4baada7f9bf 100644
--- a/build_files/scons/config/win32-vc-config.py
+++ b/build_files/scons/config/win32-vc-config.py
@@ -7,6 +7,7 @@ BF_FFMPEG = LIBDIR +'/ffmpeg'
BF_FFMPEG_INC = '${BF_FFMPEG}/include ${BF_FFMPEG}/include/msvc'
BF_FFMPEG_LIBPATH='${BF_FFMPEG}/lib'
BF_FFMPEG_LIB = 'avformat-52.lib avcodec-52.lib avdevice-52.lib avutil-50.lib swscale-0.lib'
+BF_FFMPEG_DLL = '${BF_FFMPEG_LIBPATH}/avformat-52.dll ${BF_FFMPEG_LIBPATH}/avcodec-52.dll ${BF_FFMPEG_LIBPATH}/avdevice-52.dll ${BF_FFMPEG_LIBPATH}/avutil-50.dll ${BF_FFMPEG_LIBPATH}/swscale-0.dll'
BF_PYTHON = LIBDIR + '/python'
BF_PYTHON_VERSION = '3.2'
@@ -149,6 +150,8 @@ BF_OPENCOLLADA_INC = '${BF_OPENCOLLADA}/include'
BF_OPENCOLLADA_LIB = 'OpenCOLLADAStreamWriter OpenCOLLADASaxFrameworkLoader OpenCOLLADAFramework OpenCOLLADABaseUtils GeneratedSaxParser MathMLSolver xml2 pcre buffer ftoa UTF'
BF_OPENCOLLADA_LIBPATH = '${BF_OPENCOLLADA}/lib'
+WITH_BF_3DMOUSE = True
+
#Ray trace optimization
WITH_BF_RAYOPTIMIZATION = True
BF_RAYOPTIMIZATION_SSE_FLAGS = ['/arch:SSE']
diff --git a/build_files/scons/config/win64-vc-config.py b/build_files/scons/config/win64-vc-config.py
index 67db1c441d7..db7c8d09af8 100644
--- a/build_files/scons/config/win64-vc-config.py
+++ b/build_files/scons/config/win64-vc-config.py
@@ -7,6 +7,7 @@ BF_FFMPEG = LIBDIR +'/ffmpeg'
BF_FFMPEG_INC = '${BF_FFMPEG}/include ${BF_FFMPEG}/include/msvc '
BF_FFMPEG_LIBPATH='${BF_FFMPEG}/lib'
BF_FFMPEG_LIB = 'avformat-52.lib avcodec-52.lib avdevice-52.lib avutil-50.lib swscale-0.lib'
+BF_FFMPEG_DLL = '${BF_FFMPEG_LIBPATH}/avformat-52.dll ${BF_FFMPEG_LIBPATH}/avcodec-52.dll ${BF_FFMPEG_LIBPATH}/avdevice-52.dll ${BF_FFMPEG_LIBPATH}/avutil-50.dll ${BF_FFMPEG_LIBPATH}/swscale-0.dll'
BF_PYTHON = LIBDIR + '/python'
BF_PYTHON_VERSION = '3.2'
@@ -153,6 +154,8 @@ BF_OPENCOLLADA_INC = '${BF_OPENCOLLADA}/include'
BF_OPENCOLLADA_LIB = 'OpenCOLLADAStreamWriter OpenCOLLADASaxFrameworkLoader OpenCOLLADAFramework OpenCOLLADABaseUtils GeneratedSaxParser MathMLSolver xml2 pcre buffer ftoa UTF'
BF_OPENCOLLADA_LIBPATH = '${BF_OPENCOLLADA}/lib'
+WITH_BF_3DMOUSE = True
+
#Ray trace optimization
WITH_BF_RAYOPTIMIZATION = True
BF_RAYOPTIMIZATION_SSE_FLAGS = ['/arch:SSE','/arch:SSE2']
diff --git a/build_files/scons/tools/Blender.py b/build_files/scons/tools/Blender.py
index 75af7e47edd..6fae2785192 100644
--- a/build_files/scons/tools/Blender.py
+++ b/build_files/scons/tools/Blender.py
@@ -206,6 +206,12 @@ def setup_staticlibs(lenv):
if lenv['WITH_BF_STATICJEMALLOC']:
statlibs += Split(lenv['BF_JEMALLOC_LIB_STATIC'])
+ if lenv['OURPLATFORM']=='linux2':
+ if lenv['WITH_BF_3DMOUSE']:
+ libincs += Split(lenv['BF_3DMOUSE_LIBPATH'])
+ if lenv['WITH_BF_STATIC3DMOUSE']:
+ statlibs += Split(lenv['BF_3DMOUSE_LIB_STATIC'])
+
return statlibs, libincs
def setup_syslibs(lenv):
@@ -271,6 +277,11 @@ def setup_syslibs(lenv):
if not lenv['WITH_BF_STATICJEMALLOC']:
syslibs += Split(lenv['BF_JEMALLOC_LIB'])
+ if lenv['OURPLATFORM']=='linux2':
+ if lenv['WITH_BF_3DMOUSE']:
+ if not lenv['WITH_BF_STATIC3DMOUSE']:
+ syslibs += Split(lenv['BF_3DMOUSE_LIB'])
+
syslibs += lenv['LLIBS']
return syslibs
diff --git a/build_files/scons/tools/btools.py b/build_files/scons/tools/btools.py
index 677ddab8db5..9b911b9d6f0 100644
--- a/build_files/scons/tools/btools.py
+++ b/build_files/scons/tools/btools.py
@@ -87,7 +87,7 @@ def validate_arguments(args, bc):
'BF_PTHREADS', 'BF_PTHREADS_INC', 'BF_PTHREADS_LIB', 'BF_PTHREADS_LIBPATH',
'WITH_BF_OPENEXR', 'BF_OPENEXR', 'BF_OPENEXR_INC', 'BF_OPENEXR_LIB', 'BF_OPENEXR_LIBPATH', 'WITH_BF_STATICOPENEXR', 'BF_OPENEXR_LIB_STATIC',
'WITH_BF_DDS', 'WITH_BF_CINEON', 'WITH_BF_HDR',
- 'WITH_BF_FFMPEG', 'BF_FFMPEG_LIB','BF_FFMPEG_EXTRA', 'BF_FFMPEG', 'BF_FFMPEG_INC',
+ 'WITH_BF_FFMPEG', 'BF_FFMPEG_LIB','BF_FFMPEG_EXTRA', 'BF_FFMPEG', 'BF_FFMPEG_INC', 'BF_FFMPEG_DLL',
'WITH_BF_STATICFFMPEG', 'BF_FFMPEG_LIB_STATIC',
'WITH_BF_OGG', 'BF_OGG', 'BF_OGG_LIB',
'WITH_BF_JPEG', 'BF_JPEG', 'BF_JPEG_INC', 'BF_JPEG_LIB', 'BF_JPEG_LIBPATH',
@@ -136,7 +136,7 @@ def validate_arguments(args, bc):
'BF_NO_ELBEEM',
'WITH_BF_CXX_GUARDEDALLOC',
'WITH_BF_JEMALLOC', 'WITH_BF_STATICJEMALLOC', 'BF_JEMALLOC', 'BF_JEMALLOC_INC', 'BF_JEMALLOC_LIBPATH', 'BF_JEMALLOC_LIB', 'BF_JEMALLOC_LIB_STATIC',
- 'BUILDBOT_BRANCH'
+ 'BUILDBOT_BRANCH', 'WITH_BF_3DMOUSE', 'WITH_BF_STATIC3DMOUSE', 'BF_3DMOUSE', 'BF_3DMOUSE_INC', 'BF_3DMOUSE_LIB', 'BF_3DMOUSE_LIBPATH', 'BF_3DMOUSE_LIB_STATIC'
]
# Have options here that scons expects to be lists
@@ -159,7 +159,7 @@ def validate_arguments(args, bc):
'BF_BSC', 'BF_CONFIG',
'BF_PRIORITYLIST', 'BF_BUILDINFO','CC', 'CXX', 'BF_QUICKDEBUG',
'BF_LISTDEBUG', 'LCGDIR', 'BF_X264_CONFIG', 'BF_XVIDCORE_CONFIG',
- 'BF_UNIT_TEST']
+ 'BF_UNIT_TEST', 'BF_BITNESS']
okdict = {}
@@ -291,6 +291,7 @@ def read_opts(env, cfg, args):
(BoolVariable('WITH_BF_FFMPEG', 'Use FFMPEG if true', False)),
('BF_FFMPEG', 'FFMPEG base path', ''),
('BF_FFMPEG_LIB', 'FFMPEG library', ''),
+ ('BF_FFMPEG_DLL', 'FFMPEG dll libraries to be installed', ''),
('BF_FFMPEG_EXTRA', 'FFMPEG flags that must be preserved', ''),
('BF_FFMPEG_INC', 'FFMPEG includes', ''),
@@ -437,6 +438,14 @@ def read_opts(env, cfg, args):
(BoolVariable('WITH_BF_PLAYER', 'Build blenderplayer if true', False)),
(BoolVariable('WITH_BF_NOBLENDER', 'Do not build blender if true', False)),
+ (BoolVariable('WITH_BF_3DMOUSE', 'Build blender with support of 3D mouses', False)),
+ (BoolVariable('WITH_BF_STATIC3DMOUSE', 'Staticly link to 3d mouse library', False)),
+ ('BF_3DMOUSE', '3d mouse library base path', ''),
+ ('BF_3DMOUSE_INC', '3d mouse library include path', ''),
+ ('BF_3DMOUSE_LIB', '3d mouse library', ''),
+ ('BF_3DMOUSE_LIBPATH', '3d mouse library path', ''),
+ ('BF_3DMOUSE_LIB_STATIC', '3d mouse static library', ''),
+
('CFLAGS', 'C only flags', []),
('CCFLAGS', 'Generic C and C++ flags', []),
('CXXFLAGS', 'C++ only flags', []),
diff --git a/doc/python_api/blender-org/static/default.css_t b/doc/python_api/blender-org/static/default.css_t
index 6f3f25d8a6a..e6fe922e3af 100644
--- a/doc/python_api/blender-org/static/default.css_t
+++ b/doc/python_api/blender-org/static/default.css_t
@@ -219,7 +219,7 @@ div.sphinxsidebarwrapper.fixed {
}
{%- if theme_stickysidebar|tobool %}
-/* this is nice, but it it leads to hidden headings when jumping
+/* this is nice, but it leads to hidden headings when jumping
to an anchor */
/*
div.related {
diff --git a/doc/python_api/examples/bge.constraints.py b/doc/python_api/examples/bge.constraints.py
index 4cd967310cc..de2f7e0a39d 100644
--- a/doc/python_api/examples/bge.constraints.py
+++ b/doc/python_api/examples/bge.constraints.py
@@ -8,11 +8,11 @@ from bge import constraints
# get object list
objects = logic.getCurrentScene().objects
-
+
# get object named Object1 and Object 2
object_1 = objects["Object1"]
object_2 = objects["Object2"]
-
+
# want to use Edge constraint type
constraint_type = 2
@@ -31,7 +31,7 @@ edge_angle_y = 1.0
edge_angle_z = 0.0
# create an edge constraint
-constraints.createConstraint( physics_id_1, physics_id_2,
- constraint_type,
- edge_position_x, edge_position_y, edge_position_z,
- edge_angle_x, edge_angle_y, edge_angle_z )
+constraints.createConstraint(physics_id_1, physics_id_2,
+ constraint_type,
+ edge_position_x, edge_position_y, edge_position_z,
+ edge_angle_x, edge_angle_y, edge_angle_z)
diff --git a/doc/python_api/examples/bge.texture.1.py b/doc/python_api/examples/bge.texture.1.py
index 74b37e72994..faa0ae736e8 100644
--- a/doc/python_api/examples/bge.texture.1.py
+++ b/doc/python_api/examples/bge.texture.1.py
@@ -6,29 +6,31 @@ createTexture() and removeTexture() are to be called from a module Python
Controller.
"""
from bge import logic
-from bge import texture
+from bge import texture
+
def createTexture(cont):
"""Create a new Dynamic Texture"""
object = cont.owner
-
+
# get the reference pointer (ID) of the internal texture
ID = texture.materialID(obj, 'IMoriginal.png')
-
- # create a texture object
+
+ # create a texture object
object_texture = texture.Texture(object, ID)
-
+
# create a new source with an external image
url = logic.expandPath("//newtexture.jpg")
new_source = texture.ImageFFmpeg(url)
-
+
# the texture has to be stored in a permanent Python object
logic.texture = object_texture
-
+
# update/replace the texture
logic.texture.source = new_source
logic.texture.refresh(False)
+
def removeTexture(cont):
"""Delete the Dynamic Texture, reversing back the final to its original state."""
try:
diff --git a/doc/python_api/examples/bge.texture.py b/doc/python_api/examples/bge.texture.py
index 0ec9aa16bca..70e4d6d9377 100644
--- a/doc/python_api/examples/bge.texture.py
+++ b/doc/python_api/examples/bge.texture.py
@@ -9,14 +9,14 @@ from bge import logic
cont = logic.getCurrentController()
obj = cont.owner
-
-# the creation of the texture must be done once: save the
+
+# the creation of the texture must be done once: save the
# texture object in an attribute of bge.logic module makes it persistent
if not hasattr(logic, 'video'):
-
+
# identify a static texture by name
matID = texture.materialID(obj, 'IMvideo.png')
-
+
# create a dynamic texture that will replace the static texture
logic.video = texture.Texture(obj, matID)
@@ -24,7 +24,7 @@ if not hasattr(logic, 'video'):
movie = logic.expandPath('//trailer_400p.ogg')
logic.video.source = texture.VideoFFmpeg(movie)
logic.video.source.scale = True
-
+
# quick off the movie, but it wont play in the background
logic.video.source.play()
diff --git a/doc/python_api/examples/blf.py b/doc/python_api/examples/blf.py
index 3ab7f789ce8..f6e87cf488d 100644
--- a/doc/python_api/examples/blf.py
+++ b/doc/python_api/examples/blf.py
@@ -1,6 +1,7 @@
"""
Hello World Text Example
++++++++++++++++++++++++
+
Blender Game Engine example of using the blf module. For this module to work we
need to use the OpenGL wrapper :class:`~bgl` as well.
"""
@@ -11,31 +12,33 @@ from bge import logic
import bgl
import blf
+
def init():
"""init function - runs once"""
# create a new font object, use external ttf file
font_path = logic.expandPath('//Zeyada.ttf')
- # store the font indice - to use later
+ # store the font indice - to use later
logic.font_id = blf.load(font_path)
- # set the font drawing routine to run every frame
+ # set the font drawing routine to run every frame
scene = logic.getCurrentScene()
- scene.post_draw=[write]
+ scene.post_draw = [write]
+
def write():
"""write on screen"""
width = render.getWindowWidth()
height = render.getWindowHeight()
-
+
# OpenGL setup
bgl.glMatrixMode(bgl.GL_PROJECTION)
bgl.glLoadIdentity()
bgl.gluOrtho2D(0, width, 0, height)
bgl.glMatrixMode(bgl.GL_MODELVIEW)
bgl.glLoadIdentity()
-
+
# BLF drawing routine
font_id = logic.font_id
- blf.position(font_id, (width*0.2), (height*0.3), 0)
+ blf.position(font_id, (width * 0.2), (height * 0.3), 0)
blf.size(font_id, 50, 72)
blf.draw(font_id, "Hello World")
diff --git a/doc/python_api/examples/mathutils.Vector.py b/doc/python_api/examples/mathutils.Vector.py
index 880b4ef2590..bf1fc70353f 100644
--- a/doc/python_api/examples/mathutils.Vector.py
+++ b/doc/python_api/examples/mathutils.Vector.py
@@ -1,15 +1,15 @@
import mathutils
# zero length vector
-vec = mathutils.Vector((0, 0, 1))
+vec = mathutils.Vector((0.0, 0.0, 1.0))
# unit length vector
vec_a = vec.copy().normalize()
-vec_b = mathutils.Vector((0, 1, 2))
+vec_b = mathutils.Vector((0.0, 1.0, 2.0))
-vec2d = mathutils.Vector((1, 2))
-vec3d = mathutils.Vector((1, 0, 0))
+vec2d = mathutils.Vector((1.0, 2.0))
+vec3d = mathutils.Vector((1.0, 0.0, 0.0))
vec4d = vec_a.to_4d()
# other mathutuls types
@@ -34,9 +34,9 @@ vec_a + vec_b
vec_a - vec_b
vec_a * vec_b
vec_a * 10.0
-vec_a * matrix
+matrix * vec_a
+quat * vec_a
vec_a * vec_b
-vec_a * quat
-vec_a
@@ -44,6 +44,7 @@ vec_a * quat
x = vec_a[0]
len(vec)
vec_a[:] = vec_b
+vec_a[:] = 1.0, 2.0, 3.0
vec2d[:] = vec3d[:2]
diff --git a/doc/python_api/rst/bge.constraints.rst b/doc/python_api/rst/bge.constraints.rst
index 882bbc39b9f..12ce8617457 100644
--- a/doc/python_api/rst/bge.constraints.rst
+++ b/doc/python_api/rst/bge.constraints.rst
@@ -1,28 +1,47 @@
-Game Engine bge.constraints Module
-==================================
+Physics Constraints (bge.constraints)
+=====================================
-.. note::
- This documentation is still very weak, and needs some help!
-
-.. function:: createConstraint([obj1, [obj2, [restLength, [restitution, [damping]]]]])
+.. function:: createConstraint(physicsid, physicsid2, constrainttype, [pivotX, pivotY, pivotZ, [axisX, axisY, axisZ, [flag]]]])
Creates a constraint.
- :arg obj1: first object on Constraint
- :type obj1: :class:'bge.types.KX_GameObject' #I think, there is no error when I use one
+ :arg physicsid: the physics id of the first object in constraint
+ :type physicsid: int
- :arg obj2: second object on Constraint
- :type obj2: :class:'bge.types.KX_GameObject' #too
+ :arg physicsid2: the physics id of the second object in constraint
+ :type physicsid2: int
- :arg restLength: #to be filled
- :type restLength: float
+ :arg constrainttype: the type of the constraint. The constraint types are:
- :arg restitution: #to be filled
- :type restitution: float
+ - :class:`POINTTOPOINT_CONSTRAINT`
+ - :class:`LINEHINGE_CONSTRAINT`
+ - :class:`ANGULAR_CONSTRAINT`
+ - :class:`CONETWIST_CONSTRAINT`
+ - :class:`VEHICLE_CONSTRAINT`
- :arg damping: #to be filled
- :type damping: float
+ :type constrainttype: int
+
+ :arg pivotX: pivot X position
+ :type pivotX: float
+
+ :arg pivotY: pivot Y position
+ :type pivotY: float
+
+ :arg pivotZ: pivot Z position
+ :type pivotZ: float
+
+ :arg axisX: X axis
+ :type axisX: float
+
+ :arg axisY: Y axis
+ :type axisY: float
+
+ :arg axisZ: Z axis
+ :type axisZ: float
+
+ :arg flag: .. to do
+ :type flag: int
.. attribute:: error
@@ -49,7 +68,7 @@ Game Engine bge.constraints Module
:type constraintId: int
:return: a vehicle constraint object.
- :rtype: :class:'KX_VehicleWrapper'
+ :rtype: :class:`bge.types.KX_VehicleWrapper`
.. function:: removeConstraint(constraintId)
@@ -60,10 +79,10 @@ Game Engine bge.constraints Module
.. function:: setCcdMode(ccdMode)
- ..note::
+ .. note::
Very experimental, not recommended
- Sets the CCD mode in the Physics Environment.
+ Sets the CCD (Continous Colision Detection) mode in the Physics Environment.
:arg ccdMode: The new CCD mode.
:type ccdMode: int
@@ -73,21 +92,21 @@ Game Engine bge.constraints Module
.. note::
Reasonable default is 0.02 (if units are meters)
- Sets the contact breaking treshold in the Physics Environment.
+ Sets tresholds to do with contact point management.
:arg breakingTreshold: The new contact breaking treshold.
:type breakingTreshold: float
.. function:: setDeactivationAngularTreshold(angularTreshold)
- Sets the deactivation angular treshold.
+ Sets the angular velocity treshold.
:arg angularTreshold: New deactivation angular treshold.
:type angularTreshold: float
.. function:: setDeactivationLinearTreshold(linearTreshold)
- Sets the deactivation linear treshold.
+ Sets the linear velocity treshold.
:arg linearTreshold: New deactivation linear treshold.
:type linearTreshold: float
@@ -104,21 +123,20 @@ Game Engine bge.constraints Module
Sets the debug mode.
Debug modes:
- - No debug: 0
- - Draw wireframe: 1
- - Draw Aabb: 2 #What's Aabb?
- - Draw freatures text: 4
- - Draw contact points: 8
- - No deactivation: 16
- - No help text: 32
- - Draw text: 64
- - Profile timings: 128
- - Enable sat comparision: 256
- - Disable Bullet LCP: 512
- - Enable CCD: 1024
- - Draw Constraints: #(1 << 11) = ?
- - Draw Constraint Limits: #(1 << 12) = ?
- - Fast Wireframe: #(1 << 13) = ?
+ - :class:`DBG_NODEBUG`
+ - :class:`DBG_DRAWWIREFRAME`
+ - :class:`DBG_DRAWAABB`
+ - :class:`DBG_DRAWFREATURESTEXT`
+ - :class:`DBG_DRAWCONTACTPOINTS`
+ - :class:`DBG_NOHELPTEXT`
+ - :class:`DBG_DRAWTEXT`
+ - :class:`DBG_PROFILETIMINGS`
+ - :class:`DBG_ENABLESATCOMPARISION`
+ - :class:`DBG_DISABLEBULLETLCP`
+ - :class:`DBG_ENABLECCD`
+ - :class:`DBG_DRAWCONSTRAINTS`
+ - :class:`DBG_DRAWCONSTRAINTLIMITS`
+ - :class:`DBG_FASTWIREFRAME`
:arg mode: The new debug mode.
:type mode: int
@@ -138,7 +156,10 @@ Game Engine bge.constraints Module
.. function:: setLinearAirDamping(damping)
- Not implemented.
+ .. note::
+ Not implemented.
+
+ Sets the linear air damping for rigidbodies.
.. function:: setNumIterations(numiter)
@@ -156,10 +177,10 @@ Game Engine bge.constraints Module
.. function:: setSolverDamping(damping)
- ..note::
+ .. note::
Very experimental, not recommended
- Sets the solver damping.
+ Sets the damper constant of a penalty based solver.
:arg damping: New damping for the solver.
:type damping: float
@@ -169,7 +190,7 @@ Game Engine bge.constraints Module
.. note::
Very experimental, not recommended
- Sets the solver tau.
+ Sets the spring constant of a penalty based solver.
:arg tau: New tau for the solver.
:type tau: float
@@ -189,7 +210,7 @@ Game Engine bge.constraints Module
.. note::
Very experimental, not recommended
- Sets the sor constant.
+ Sets the successive overrelaxation constant.
:arg sor: New sor value.
:type sor: float
@@ -197,3 +218,136 @@ Game Engine bge.constraints Module
.. function:: setUseEpa(epa)
Not implemented.
+
+.. data:: DBG_NODEBUG
+
+ .. note::
+ Debug mode to be used with function :class:`setDebugMode`
+
+ No debug.
+
+.. data:: DBG_DRAWWIREFRAME
+
+ .. note::
+ Debug mode to be used with function :class:`setDebugMode`
+
+ Draw wireframe in debug.
+
+.. data:: DBG_DRAWAABB
+
+ .. note::
+ Debug mode to be used with function :class:`setDebugMode`
+
+ Draw Axis Aligned Bounding Box in debug.
+
+.. data:: DBG_DRAWFREATURESTEXT
+
+ .. note::
+ Debug mode to be used with function :class:`setDebugMode`
+
+ Draw freatures text in debug.
+
+.. data:: DBG_DRAWCONTACTPOINTS
+
+ .. note::
+ Debug mode to be used with function :class:`setDebugMode`
+
+ Draw contact points in debug.
+
+.. data:: DBG_NOHELPTEXT
+
+ .. note::
+ Debug mode to be used with function :class:`setDebugMode`
+
+ Debug without help text.
+
+.. data:: DBG_DRAWTEXT
+
+ .. note::
+ Debug mode to be used with function :class:`setDebugMode`
+
+ Draw text in debug.
+
+.. data:: DBG_PROFILETIMINGS
+
+ .. note::
+ Debug mode to be used with function :class:`setDebugMode`
+
+ Draw profile timings in debug.
+
+.. data:: DBG_ENABLESATCOMPARISION
+
+ .. note::
+ Debug mode to be used with function :class:`setDebugMode`
+
+ Enable sat comparision in debug.
+
+.. data:: DBG_DISABLEBULLETLCP
+
+ .. note::
+ Debug mode to be used with function :class:`setDebugMode`
+
+ Disable Bullet LCP.
+
+.. data:: DBG_ENABLECCD
+
+ .. note::
+ Debug mode to be used with function :class:`setDebugMode`
+
+ Enable Continous Colision Detection in debug.
+
+.. data:: DBG_DRAWCONSTRAINTS
+
+ .. note::
+ Debug mode to be used with function :class:`setDebugMode`
+
+ Draw constraints in debug.
+
+.. data:: DBG_DRAWCONSTRAINTLIMITS
+
+ .. note::
+ Debug mode to be used with function :class:`setDebugMode`
+
+ Draw constraint limits in debug.
+
+.. data:: DBG_FASTWIREFRAME
+
+ .. note::
+ Debug mode to be used with function :class:`setDebugMode`
+
+ Draw a fast wireframe in debug.
+
+.. data:: POINTTOPOINT_CONSTRAINT
+
+ .. note::
+ Constraint type to be used with function :class:`createConstraint`
+
+ .. to do
+
+.. data:: LINEHINGE_CONSTRAINT
+
+ .. note::
+ Constraint type to be used with function :class:`createConstraint`
+
+ .. to do
+
+.. data:: ANGULAR_CONSTRAINT
+
+ .. note::
+ Constraint type to be used with function :class:`createConstraint`
+
+ .. to do
+
+.. data:: CONETWIST_CONSTRAINT
+
+ .. note::
+ Constraint type to be used with function :class:`createConstraint`
+
+ .. to do
+
+.. data:: VEHICLE_CONSTRAINT
+
+ .. note::
+ Constraint type to be used with function :class:`createConstraint`
+
+ .. to do
diff --git a/doc/python_api/rst/bge.events.rst b/doc/python_api/rst/bge.events.rst
index cc76ecded85..074e928f0d8 100644
--- a/doc/python_api/rst/bge.events.rst
+++ b/doc/python_api/rst/bge.events.rst
@@ -1,6 +1,6 @@
-Game Engine bge.events Module
-=============================
+Game Keys (bge.events)
+======================
*****
Intro
diff --git a/doc/python_api/rst/bge.logic.rst b/doc/python_api/rst/bge.logic.rst
index f7163ea928e..128f87f76bd 100644
--- a/doc/python_api/rst/bge.logic.rst
+++ b/doc/python_api/rst/bge.logic.rst
@@ -1,6 +1,7 @@
-Game Engine bge.logic Module
-============================
+Game Logic (bge.logic)
+======================
+
*****
Intro
*****
diff --git a/doc/python_api/rst/bge.render.rst b/doc/python_api/rst/bge.render.rst
index 9f17455601b..10514049a8a 100644
--- a/doc/python_api/rst/bge.render.rst
+++ b/doc/python_api/rst/bge.render.rst
@@ -1,6 +1,6 @@
-Game Engine bge.render Module
-=============================
+Rasterizer (bge.render)
+=======================
*****
Intro
@@ -16,8 +16,8 @@ Intro
import bge.render
import bge.logic
- # SCALE sets the speed of motion
- SCALE=[1, 0.5]
+ # scale sets the speed of motion
+ scale = 1.0, 0.5
co = bge.logic.getCurrentController()
obj = co.getOwner()
@@ -27,8 +27,8 @@ Intro
# Transform the mouse coordinates to see how far the mouse has moved.
def mousePos():
- x = (bge.render.getWindowWidth()/2 - mouse.getXPosition())*SCALE[0]
- y = (bge.render.getWindowHeight()/2 - mouse.getYPosition())*SCALE[1]
+ x = (bge.render.getWindowWidth() / 2 - mouse.getXPosition()) * scale[0]
+ y = (bge.render.getWindowHeight() / 2 - mouse.getYPosition()) * scale[1]
return (x, y)
pos = mousePos()
@@ -43,7 +43,7 @@ Intro
bge.logic.addActiveActuator(wmotion, True)
# Centre the mouse
- bge.render.setMousePosition(bge.render.getWindowWidth()/2, bge.render.getWindowHeight()/2)
+ bge.render.setMousePosition(bge.render.getWindowWidth() / 2, bge.render.getWindowHeight() / 2)
*********
Constants
diff --git a/doc/python_api/rst/bge.texture.rst b/doc/python_api/rst/bge.texture.rst
index 996f79a313a..f3e9f98dded 100644
--- a/doc/python_api/rst/bge.texture.rst
+++ b/doc/python_api/rst/bge.texture.rst
@@ -1,10 +1,6 @@
-Game Engine bge.texture Module
-==============================
-
-.. note::
- This documentation is still very weak, and needs some help! Right now they are mostly a collection
- of the docstrings found in the bge.texture source code + some random places filled with text.
+Video Texture (bge.texture)
+===========================
*****
Intro
diff --git a/doc/python_api/rst/bge.types.rst b/doc/python_api/rst/bge.types.rst
index e42b362c771..36ef9154e17 100644
--- a/doc/python_api/rst/bge.types.rst
+++ b/doc/python_api/rst/bge.types.rst
@@ -1,6 +1,6 @@
-Game Engine bge.types Module
-=============================
+Game Types (bge.types)
+======================
.. module:: bge.types
diff --git a/doc/python_api/rst/bgl.rst b/doc/python_api/rst/bgl.rst
index 76b7442f2c5..236bfafb295 100644
--- a/doc/python_api/rst/bgl.rst
+++ b/doc/python_api/rst/bgl.rst
@@ -1,6 +1,6 @@
-bgl module (OpenGL wrapper)
-===========================
+OpenGL Wrapper (bgl)
+====================
.. module:: bgl
@@ -71,8 +71,8 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
.. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/begin.html>`_
:type mode: Enumerated constant
- :arg mode: Specifies the primitive that will be create from vertices between glBegin and
- glEnd.
+ :arg mode: Specifies the primitive that will be create from vertices between
+ glBegin and glEnd.
.. function:: glBindTexture(target, texture):
@@ -1886,4 +1886,3 @@ class Buffer:
the Buffer. If a template is not passed in all fields will be initialized to 0.
:rtype: Buffer object
:return: The newly created buffer as a PyObject.
-
diff --git a/doc/python_api/sphinx_doc_gen.py b/doc/python_api/sphinx_doc_gen.py
index 6b514cf9eb1..f8561c719bc 100644
--- a/doc/python_api/sphinx_doc_gen.py
+++ b/doc/python_api/sphinx_doc_gen.py
@@ -416,6 +416,7 @@ def pymodule2sphinx(BASEPATH, module_name, module, title):
del key, descr
classes = []
+ submodules = []
for attribute in module_dir:
if not attribute.startswith("_"):
@@ -437,6 +438,8 @@ def pymodule2sphinx(BASEPATH, module_name, module, title):
py_c_func2sphinx("", fw, module_name, None, attribute, value, is_class=False)
elif value_type == type:
classes.append((attribute, value))
+ elif issubclass(value_type, types.ModuleType):
+ submodules.append((attribute, value))
elif value_type in (bool, int, float, str, tuple):
# constant, not much fun we can do here except to list it.
# TODO, figure out some way to document these!
@@ -444,12 +447,26 @@ def pymodule2sphinx(BASEPATH, module_name, module, title):
write_indented_lines(" ", fw, "constant value %s" % repr(value), False)
fw("\n")
else:
- print("\tnot documenting %s.%s" % (module_name, attribute))
+ print("\tnot documenting %s.%s of %r type" % (module_name, attribute, value_type.__name__))
continue
attribute_set.add(attribute)
# TODO, more types...
+ # TODO, bpy_extras does this already, mathutils not.
+ """
+ if submodules:
+ fw("\n"
+ "**********\n"
+ "Submodules\n"
+ "**********\n"
+ "\n"
+ )
+ for attribute, submod in submodules:
+ fw("* :mod:`%s.%s`\n" % (module_name, attribute))
+ fw("\n")
+ """
+
# write collected classes now
for (type_name, value) in classes:
# May need to be its own function
diff --git a/doc/python_api/sphinx_doc_gen.sh b/doc/python_api/sphinx_doc_gen.sh
index 5f23ca395b6..a3befe1b7cb 100755
--- a/doc/python_api/sphinx_doc_gen.sh
+++ b/doc/python_api/sphinx_doc_gen.sh
@@ -38,8 +38,11 @@ cp $SPHINXBASE/sphinx-out/contents.html $SPHINXBASE/sphinx-out/index.html
ssh $SSH_USER@emo.blender.org 'rm -rf '$SSH_UPLOAD_FULL'/*'
rsync --progress -avze "ssh -p 22" $SPHINXBASE/sphinx-out/* $SSH_HOST:$SSH_UPLOAD_FULL/
-# symlink the dir to a static URL
-ssh $SSH_USER@emo.blender.org 'rm '$SSH_UPLOAD'/250PythonDoc && ln -s '$SSH_UPLOAD_FULL' '$SSH_UPLOAD'/250PythonDoc'
+## symlink the dir to a static URL
+#ssh $SSH_USER@emo.blender.org 'rm '$SSH_UPLOAD'/250PythonDoc && ln -s '$SSH_UPLOAD_FULL' '$SSH_UPLOAD'/250PythonDoc'
+
+# better redirect
+ssh $SSH_USER@emo.blender.org 'echo "<html><head><title>Redirecting...</title><meta http-equiv=\"REFRESH\" content=\"0;url=../blender_python_api_'$BLENDER_VERSION'/\"></head><body>Redirecting...</body></html>" > '$SSH_UPLOAD'/250PythonDoc/index.html'
# pdf
sphinx-build -b latex $SPHINXBASE/sphinx-in $SPHINXBASE/sphinx-out
diff --git a/intern/ghost/CMakeLists.txt b/intern/ghost/CMakeLists.txt
index ccd763ef42c..d7658c50a36 100644
--- a/intern/ghost/CMakeLists.txt
+++ b/intern/ghost/CMakeLists.txt
@@ -44,7 +44,6 @@ set(SRC
intern/GHOST_ISystem.cpp
intern/GHOST_ISystemPaths.cpp
intern/GHOST_ModifierKeys.cpp
- intern/GHOST_NDOFManager.cpp
intern/GHOST_Path-api.cpp
intern/GHOST_Path-api.cpp
intern/GHOST_Rect.cpp
@@ -74,12 +73,10 @@ set(SRC
intern/GHOST_EventDragnDrop.h
intern/GHOST_EventKey.h
intern/GHOST_EventManager.h
- intern/GHOST_EventNDOF.h
intern/GHOST_EventString.h
intern/GHOST_EventTrackpad.h
intern/GHOST_EventWheel.h
intern/GHOST_ModifierKeys.h
- intern/GHOST_NDOFManager.h
intern/GHOST_System.h
intern/GHOST_SystemPaths.h
intern/GHOST_TimerManager.h
@@ -97,6 +94,20 @@ if(WITH_GHOST_DEBUG)
add_definitions(-DWITH_GHOST_DEBUG)
endif()
+if(WITH_INPUT_NDOF)
+ add_definitions(-DWITH_INPUT_NDOF)
+
+ list(APPEND SRC
+ intern/GHOST_NDOFManager.cpp
+
+ intern/GHOST_EventNDOF.h
+ intern/GHOST_NDOFManager.h
+ )
+
+ list(APPEND INC_SYS
+ ${NDOF_INCLUDE_DIRS}
+ )
+endif()
if(WITH_HEADLESS OR WITH_GHOST_SDL)
if(WITH_HEADLESS)
@@ -158,12 +169,21 @@ elseif(APPLE)
intern/GHOST_SystemCocoa.mm
intern/GHOST_SystemPathsCocoa.mm
intern/GHOST_WindowCocoa.mm
-
+
intern/GHOST_DisplayManagerCocoa.h
intern/GHOST_SystemCocoa.h
intern/GHOST_SystemPathsCocoa.h
intern/GHOST_WindowCocoa.h
)
+
+ if(WITH_INPUT_NDOF)
+ list(APPEND SRC
+ intern/GHOST_NDOFManagerCocoa.mm
+
+ intern/GHOST_NDOFManagerCocoa.h
+ )
+ endif()
+
else()
list(APPEND SRC
intern/GHOST_DisplayManagerCarbon.cpp
@@ -215,6 +235,14 @@ elseif(UNIX)
)
endif()
+ if(WITH_INPUT_NDOF)
+ list(APPEND SRC
+ intern/GHOST_NDOFManagerX11.cpp
+
+ intern/GHOST_NDOFManagerX11.h
+ )
+ endif()
+
elseif(WIN32)
if(MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /WX")
@@ -238,6 +266,15 @@ elseif(WIN32)
intern/GHOST_WindowWin32.h
intern/GHOST_TaskbarWin32.h
)
+
+ if(WITH_INPUT_NDOF)
+ list(APPEND SRC
+ intern/GHOST_NDOFManagerWin32.cpp
+
+ intern/GHOST_NDOFManagerWin32.h
+ )
+ endif()
+
endif()
blender_add_lib(bf_intern_ghost "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/intern/ghost/GHOST_C-api.h b/intern/ghost/GHOST_C-api.h
index 75837239c4a..a315dfa85e9 100644
--- a/intern/ghost/GHOST_C-api.h
+++ b/intern/ghost/GHOST_C-api.h
@@ -288,21 +288,6 @@ extern GHOST_TSuccess GHOST_SetProgressBar(GHOST_WindowHandle windowhandle, floa
* @param windowhandle The handle to the window
*/
extern GHOST_TSuccess GHOST_EndProgressBar(GHOST_WindowHandle windowhandle);
-
-
-/***************************************************************************************
- ** N-degree of freedom device management functionality
- ***************************************************************************************/
-
-/**
-* Open N-degree of freedom devices
- */
-extern int GHOST_OpenNDOF(GHOST_SystemHandle systemhandle,
- GHOST_WindowHandle windowhandle,
- GHOST_NDOFLibraryInit_fp setNdofLibraryInit,
- GHOST_NDOFLibraryShutdown_fp setNdofLibraryShutdown,
- GHOST_NDOFDeviceOpen_fp setNdofDeviceOpen
- );
/***************************************************************************************
** Cursor management functionality
diff --git a/intern/ghost/GHOST_ISystem.h b/intern/ghost/GHOST_ISystem.h
index 69e10070be5..015ae780bea 100644
--- a/intern/ghost/GHOST_ISystem.h
+++ b/intern/ghost/GHOST_ISystem.h
@@ -298,22 +298,6 @@ public:
*/
virtual GHOST_TSuccess removeEventConsumer(GHOST_IEventConsumer* consumer) = 0;
- /***************************************************************************************
- ** N-degree of freedom device management functionality
- ***************************************************************************************/
-
- /**
- * Starts the N-degree of freedom device manager
- */
- virtual int openNDOF(GHOST_IWindow*,
- GHOST_NDOFLibraryInit_fp setNdofLibraryInit,
- GHOST_NDOFLibraryShutdown_fp setNdofLibraryShutdown,
- GHOST_NDOFDeviceOpen_fp setNdofDeviceOpen
- // original patch only
- // GHOST_NDOFEventHandler_fp setNdofEventHandler
- ) = 0;
-
-
/***************************************************************************************
** Cursor management functionality
***************************************************************************************/
diff --git a/intern/ghost/GHOST_Types.h b/intern/ghost/GHOST_Types.h
index 6a4da5c9d38..f24ab00acd3 100644
--- a/intern/ghost/GHOST_Types.h
+++ b/intern/ghost/GHOST_Types.h
@@ -47,11 +47,6 @@ typedef unsigned short GHOST_TUns16;
typedef int GHOST_TInt32;
typedef unsigned int GHOST_TUns32;
-#ifdef WIN32
-#define WM_BLND_NDOF_AXIS WM_USER + 1
-#define WM_BLND_NDOF_BTN WM_USER + 2
-#endif
-
#if defined(WIN32) && !defined(FREE_WINDOWS)
typedef __int64 GHOST_TInt64;
typedef unsigned __int64 GHOST_TUns64;
@@ -440,37 +435,33 @@ typedef struct {
GHOST_TUns8 **strings;
} GHOST_TStringArray;
+typedef enum {
+ GHOST_kNotStarted,
+ GHOST_kStarting,
+ GHOST_kInProgress,
+ GHOST_kFinishing,
+ GHOST_kFinished
+ } GHOST_TProgress;
-/* original patch used floats, but the driver return ints and uns. We will calibrate in view, no sense on doing conversions twice */
-/* as all USB device controls are likely to use ints, this is also more future proof */
-//typedef struct {
-// /** N-degree of freedom device data */
-// float tx, ty, tz; /** -x left, +y up, +z forward */
-// float rx, ry, rz;
-// float dt;
-//} GHOST_TEventNDOFData;
+typedef struct {
+ /** N-degree of freedom device data v3 [GSoC 2010] */
+ // Each component normally ranges from -1 to +1, but can exceed that.
+ // These use blender standard view coordinates, with positive rotations being CCW about the axis.
+ float tx, ty, tz; // translation
+ float rx, ry, rz; // rotation:
+ // axis = (rx,ry,rz).normalized
+ // amount = (rx,ry,rz).magnitude [in revolutions, 1.0 = 360 deg]
+ float dt; // time since previous NDOF Motion event
+ GHOST_TProgress progress; // Starting, InProgress or Finishing (for modal handlers)
+} GHOST_TEventNDOFMotionData;
+
+typedef enum { GHOST_kPress, GHOST_kRelease } GHOST_TButtonAction;
+ // good for mouse or other buttons too, hmmm?
typedef struct {
- /** N-degree of freedom device data v2*/
- int changed;
- GHOST_TUns64 client;
- GHOST_TUns64 address;
- GHOST_TInt16 tx, ty, tz; /** -x left, +y up, +z forward */
- GHOST_TInt16 rx, ry, rz;
- GHOST_TInt16 buttons;
- GHOST_TUns64 time;
- GHOST_TUns64 delta;
-} GHOST_TEventNDOFData;
-
-typedef int (*GHOST_NDOFLibraryInit_fp)(void);
-typedef void (*GHOST_NDOFLibraryShutdown_fp)(void* deviceHandle);
-typedef void* (*GHOST_NDOFDeviceOpen_fp)(void* platformData);
-
-// original patch windows callback. In mac os X version the callback is internal to the plug-in and post an event to main thead.
-// not necessary faster, but better integration with other events.
-
-//typedef int (*GHOST_NDOFEventHandler_fp)(float* result7, void* deviceHandle, unsigned int message, unsigned int* wParam, unsigned long* lParam);
-//typedef void (*GHOST_NDOFCallBack_fp)(GHOST_TEventNDOFDataV2 *VolDatas);
+ GHOST_TButtonAction action;
+ short button;
+} GHOST_TEventNDOFButtonData;
typedef struct {
/** The key code. */
diff --git a/intern/ghost/SConscript b/intern/ghost/SConscript
index c65ec58a97b..234fc0a172e 100644
--- a/intern/ghost/SConscript
+++ b/intern/ghost/SConscript
@@ -11,7 +11,7 @@ if window_system == 'darwin':
sources += env.Glob('intern/*.mm')
-pf = ['GHOST_DisplayManager', 'GHOST_System', 'GHOST_SystemPaths', 'GHOST_Window', 'GHOST_DropTarget']
+pf = ['GHOST_DisplayManager', 'GHOST_System', 'GHOST_SystemPaths', 'GHOST_Window', 'GHOST_DropTarget', 'GHOST_NDOFManager']
defs=['_USE_MATH_DEFINES']
incs = '. ../string #extern/glew/include #source/blender/imbuf #source/blender/makesdna ' + env['BF_OPENGL_INC']
@@ -76,7 +76,25 @@ else:
if env['BF_GHOST_DEBUG']:
defs.append('WITH_GHOST_DEBUG')
else:
- sources.remove('intern' + os.sep + 'GHOST_EventPrinter.cpp')
+ sources.remove('intern' + os.sep + 'GHOST_EventPrinter.cpp')
+
+if env['WITH_BF_3DMOUSE']:
+ defs.append('WITH_INPUT_NDOF')
+
+ if env['OURPLATFORM']=='linux2':
+ incs += ' ' + env['BF_3DMOUSE_INC']
+else:
+ sources.remove('intern' + os.sep + 'GHOST_NDOFManager.cpp')
+ try:
+ if window_system in ('win32-vc', 'win32-mingw', 'cygwin', 'linuxcross', 'win64-vc'):
+ sources.remove('intern' + os.sep + 'GHOST_NDOFManagerWin32.cpp')
+ elif window_system=='darwin':
+ sources.remove('intern' + os.sep + 'GHOST_NDOFManagerCocoa.mm')
+ else:
+ sources.remove('intern' + os.sep + 'GHOST_NDOFManagerX11.cpp')
+ except ValueError:
+ pass
+
if window_system in ('win32-vc', 'win32-mingw', 'cygwin', 'linuxcross', 'win64-vc'):
incs = env['BF_WINTAB_INC'] + ' ' + incs
diff --git a/intern/ghost/intern/GHOST_C-api.cpp b/intern/ghost/intern/GHOST_C-api.cpp
index 7ba8d7db411..6332d72a42f 100644
--- a/intern/ghost/intern/GHOST_C-api.cpp
+++ b/intern/ghost/intern/GHOST_C-api.cpp
@@ -275,23 +275,6 @@ GHOST_TSuccess GHOST_EndProgressBar(GHOST_WindowHandle windowhandle)
}
-int GHOST_OpenNDOF(GHOST_SystemHandle systemhandle, GHOST_WindowHandle windowhandle,
- GHOST_NDOFLibraryInit_fp setNdofLibraryInit,
- GHOST_NDOFLibraryShutdown_fp setNdofLibraryShutdown,
- GHOST_NDOFDeviceOpen_fp setNdofDeviceOpen)
- //original patch only
- /* GHOST_NDOFEventHandler_fp setNdofEventHandler)*/
-{
- GHOST_ISystem* system = (GHOST_ISystem*) systemhandle;
-
- return system->openNDOF((GHOST_IWindow*) windowhandle,
- setNdofLibraryInit, setNdofLibraryShutdown, setNdofDeviceOpen);
-// original patch
-// setNdofLibraryInit, setNdofLibraryShutdown, setNdofDeviceOpen, setNdofEventHandler);
-}
-
-
-
GHOST_TStandardCursor GHOST_GetCursorShape(GHOST_WindowHandle windowhandle)
{
GHOST_IWindow* window = (GHOST_IWindow*) windowhandle;
diff --git a/intern/ghost/intern/GHOST_DisplayManagerWin32.cpp b/intern/ghost/intern/GHOST_DisplayManagerWin32.cpp
index 30d9aa31207..47f748927ab 100644
--- a/intern/ghost/intern/GHOST_DisplayManagerWin32.cpp
+++ b/intern/ghost/intern/GHOST_DisplayManagerWin32.cpp
@@ -35,8 +35,11 @@
#include "GHOST_DisplayManagerWin32.h"
#include "GHOST_Debug.h"
-// We do not support multiple monitors at the moment
+#define _WIN32_WINNT 0x501 // require Windows XP or newer
+#define WIN32_LEAN_AND_MEAN
#include <windows.h>
+
+// We do not support multiple monitors at the moment
#define COMPILE_MULTIMON_STUBS
#ifndef FREE_WINDOWS
#include <multimon.h>
diff --git a/intern/ghost/intern/GHOST_DropTargetWin32.cpp b/intern/ghost/intern/GHOST_DropTargetWin32.cpp
index 2e77da42b31..99990a46c2a 100644
--- a/intern/ghost/intern/GHOST_DropTargetWin32.cpp
+++ b/intern/ghost/intern/GHOST_DropTargetWin32.cpp
@@ -33,6 +33,7 @@
#include "GHOST_Debug.h"
#include "GHOST_DropTargetWin32.h"
+#include <ShellApi.h>
#ifdef GHOST_DEBUG
// utility
diff --git a/intern/ghost/intern/GHOST_DropTargetWin32.h b/intern/ghost/intern/GHOST_DropTargetWin32.h
index 0a553b6701e..980e9f9fe9b 100644
--- a/intern/ghost/intern/GHOST_DropTargetWin32.h
+++ b/intern/ghost/intern/GHOST_DropTargetWin32.h
@@ -33,7 +33,6 @@
#ifndef _GHOST_DROP_TARGET_WIN32_H_
#define _GHOST_DROP_TARGET_WIN32_H_
-#include <windows.h>
#include <string.h>
#include <GHOST_Types.h>
#include "GHOST_WindowWin32.h"
diff --git a/intern/ghost/intern/GHOST_EventManager.cpp b/intern/ghost/intern/GHOST_EventManager.cpp
index 1483555c362..86b87973038 100644
--- a/intern/ghost/intern/GHOST_EventManager.cpp
+++ b/intern/ghost/intern/GHOST_EventManager.cpp
@@ -42,7 +42,7 @@
#include "GHOST_EventManager.h"
#include <algorithm>
#include "GHOST_Debug.h"
-
+#include <stdio.h> // [mce] temp debug
GHOST_EventManager::GHOST_EventManager()
{
diff --git a/intern/ghost/intern/GHOST_EventNDOF.h b/intern/ghost/intern/GHOST_EventNDOF.h
index 70861b08fc6..394aff0493f 100644
--- a/intern/ghost/intern/GHOST_EventNDOF.h
+++ b/intern/ghost/intern/GHOST_EventNDOF.h
@@ -19,11 +19,6 @@
*
* ***** END GPL LICENSE BLOCK *****
*/
-
-/** \file ghost/intern/GHOST_EventNDOF.h
- * \ingroup GHOST
- */
-
#ifndef _GHOST_EVENT_NDOF_H_
@@ -31,32 +26,33 @@
#include "GHOST_Event.h"
-/**
- * N-degree of freedom device event.
- */
-class GHOST_EventNDOF : public GHOST_Event
-{
-public:
- /**
- * Constructor.
- * @param msec The time this event was generated.
- * @param type The type of this event.
- * @param x The x-coordinate of the location the cursor was at at the time of the event.
- * @param y The y-coordinate of the location the cursor was at at the time of the event.
- */
- GHOST_EventNDOF(GHOST_TUns64 msec, GHOST_TEventType type, GHOST_IWindow* window,
- GHOST_TEventNDOFData data)
- : GHOST_Event(msec, type, window)
- {
- m_ndofEventData = data;
- m_data = &m_ndofEventData;
- }
-protected:
- /** translation & rotation from the device. */
- GHOST_TEventNDOFData m_ndofEventData;
-};
+class GHOST_EventNDOFMotion : public GHOST_Event
+ {
+ protected:
+ GHOST_TEventNDOFMotionData m_axisData;
+
+ public:
+ GHOST_EventNDOFMotion(GHOST_TUns64 time, GHOST_IWindow* window)
+ : GHOST_Event(time, GHOST_kEventNDOFMotion, window)
+ {
+ m_data = &m_axisData;
+ }
+ };
+
+
+class GHOST_EventNDOFButton : public GHOST_Event
+ {
+ protected:
+ GHOST_TEventNDOFButtonData m_buttonData;
+
+ public:
+ GHOST_EventNDOFButton(GHOST_TUns64 time, GHOST_IWindow* window)
+ : GHOST_Event(time, GHOST_kEventNDOFButton, window)
+ {
+ m_data = &m_buttonData;
+ }
+ };
#endif // _GHOST_EVENT_NDOF_H_
-
diff --git a/intern/ghost/intern/GHOST_NDOFManager.cpp b/intern/ghost/intern/GHOST_NDOFManager.cpp
index dae6cb5b544..855e27b9964 100644
--- a/intern/ghost/intern/GHOST_NDOFManager.cpp
+++ b/intern/ghost/intern/GHOST_NDOFManager.cpp
@@ -1,4 +1,6 @@
/*
+ * $Id$
+ *
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
@@ -15,122 +17,458 @@
* 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): none yet.
+ * Contributor(s):
+ * Mike Erwin
*
* ***** END GPL LICENSE BLOCK *****
*/
-/** \file ghost/intern/GHOST_NDOFManager.cpp
- * \ingroup GHOST
- */
+#include "GHOST_Debug.h"
+#include "GHOST_NDOFManager.h"
+#include "GHOST_EventNDOF.h"
+#include "GHOST_EventKey.h"
+#include "GHOST_WindowManager.h"
+#include <string.h> // for memory functions
+#include <stdio.h> // for error/info reporting
+#include <math.h>
+#ifdef DEBUG_NDOF_MOTION
+// printable version of each GHOST_TProgress value
+static const char* progress_string[] =
+ {"not started","starting","in progress","finishing","finished"};
+#endif
-#include <stdio.h> /* just for printf */
+#ifdef DEBUG_NDOF_BUTTONS
+static const char* ndof_button_names[] = {
+ // used internally, never sent
+ "NDOF_BUTTON_NONE",
+ // these two are available from any 3Dconnexion device
+ "NDOF_BUTTON_MENU",
+ "NDOF_BUTTON_FIT",
+ // standard views
+ "NDOF_BUTTON_TOP",
+ "NDOF_BUTTON_BOTTOM",
+ "NDOF_BUTTON_LEFT",
+ "NDOF_BUTTON_RIGHT",
+ "NDOF_BUTTON_FRONT",
+ "NDOF_BUTTON_BACK",
+ // more views
+ "NDOF_BUTTON_ISO1",
+ "NDOF_BUTTON_ISO2",
+ // 90 degree rotations
+ "NDOF_BUTTON_ROLL_CW",
+ "NDOF_BUTTON_ROLL_CCW",
+ "NDOF_BUTTON_SPIN_CW",
+ "NDOF_BUTTON_SPIN_CCW",
+ "NDOF_BUTTON_TILT_CW",
+ "NDOF_BUTTON_TILT_CCW",
+ // device control
+ "NDOF_BUTTON_ROTATE",
+ "NDOF_BUTTON_PANZOOM",
+ "NDOF_BUTTON_DOMINANT",
+ "NDOF_BUTTON_PLUS",
+ "NDOF_BUTTON_MINUS",
+ // general-purpose buttons
+ "NDOF_BUTTON_1",
+ "NDOF_BUTTON_2",
+ "NDOF_BUTTON_3",
+ "NDOF_BUTTON_4",
+ "NDOF_BUTTON_5",
+ "NDOF_BUTTON_6",
+ "NDOF_BUTTON_7",
+ "NDOF_BUTTON_8",
+ "NDOF_BUTTON_9",
+ "NDOF_BUTTON_10",
+};
+#endif
-#include "GHOST_NDOFManager.h"
+static const NDOF_ButtonT SpaceNavigator_HID_map[] = {
+ NDOF_BUTTON_MENU,
+ NDOF_BUTTON_FIT
+};
+static const NDOF_ButtonT SpaceExplorer_HID_map[] = {
+ NDOF_BUTTON_1,
+ NDOF_BUTTON_2,
+ NDOF_BUTTON_TOP,
+ NDOF_BUTTON_LEFT,
+ NDOF_BUTTON_RIGHT,
+ NDOF_BUTTON_FRONT,
+ NDOF_BUTTON_NONE, // esc key
+ NDOF_BUTTON_NONE, // alt key
+ NDOF_BUTTON_NONE, // shift key
+ NDOF_BUTTON_NONE, // ctrl key
+ NDOF_BUTTON_FIT,
+ NDOF_BUTTON_MENU,
+ NDOF_BUTTON_PLUS,
+ NDOF_BUTTON_MINUS,
+ NDOF_BUTTON_ROTATE
+};
-// the variable is outside the class because it must be accessed from plugin
-static volatile GHOST_TEventNDOFData currentNdofValues = {0,0,0,0,0,0,0,0,0,0,0};
+static const NDOF_ButtonT SpacePilotPro_HID_map[] = {
+ NDOF_BUTTON_MENU,
+ NDOF_BUTTON_FIT,
+ NDOF_BUTTON_TOP,
+ NDOF_BUTTON_LEFT,
+ NDOF_BUTTON_RIGHT,
+ NDOF_BUTTON_FRONT,
+ NDOF_BUTTON_BOTTOM,
+ NDOF_BUTTON_BACK,
+ NDOF_BUTTON_ROLL_CW,
+ NDOF_BUTTON_ROLL_CCW,
+ NDOF_BUTTON_ISO1,
+ NDOF_BUTTON_ISO2,
+ NDOF_BUTTON_1,
+ NDOF_BUTTON_2,
+ NDOF_BUTTON_3,
+ NDOF_BUTTON_4,
+ NDOF_BUTTON_5,
+ NDOF_BUTTON_6,
+ NDOF_BUTTON_7,
+ NDOF_BUTTON_8,
+ NDOF_BUTTON_9,
+ NDOF_BUTTON_10,
+ NDOF_BUTTON_NONE, // esc key
+ NDOF_BUTTON_NONE, // alt key
+ NDOF_BUTTON_NONE, // shift key
+ NDOF_BUTTON_NONE, // ctrl key
+ NDOF_BUTTON_ROTATE,
+ NDOF_BUTTON_PANZOOM,
+ NDOF_BUTTON_DOMINANT,
+ NDOF_BUTTON_PLUS,
+ NDOF_BUTTON_MINUS
+};
-#if !defined(_WIN32) && !defined(__APPLE__)
-#include "GHOST_SystemX11.h"
-#endif
+/* this is the older SpacePilot (sans Pro)
+ * thanks to polosson for the info in this table */
+static const NDOF_ButtonT SpacePilot_HID_map[] = {
+ NDOF_BUTTON_1,
+ NDOF_BUTTON_2,
+ NDOF_BUTTON_3,
+ NDOF_BUTTON_4,
+ NDOF_BUTTON_5,
+ NDOF_BUTTON_6,
+ NDOF_BUTTON_TOP,
+ NDOF_BUTTON_LEFT,
+ NDOF_BUTTON_RIGHT,
+ NDOF_BUTTON_FRONT,
+ NDOF_BUTTON_NONE, // esc key
+ NDOF_BUTTON_NONE, // alt key
+ NDOF_BUTTON_NONE, // shift key
+ NDOF_BUTTON_NONE, // ctrl key
+ NDOF_BUTTON_FIT,
+ NDOF_BUTTON_MENU,
+ NDOF_BUTTON_PLUS,
+ NDOF_BUTTON_MINUS,
+ NDOF_BUTTON_DOMINANT,
+ NDOF_BUTTON_ROTATE,
+ NDOF_BUTTON_NONE // the CONFIG button -- what does it do?
+};
-namespace
+GHOST_NDOFManager::GHOST_NDOFManager(GHOST_System& sys)
+ : m_system(sys)
+ , m_deviceType(NDOF_UnknownDevice) // each platform has its own device detection code
+ , m_buttonCount(0)
+ , m_buttonMask(0)
+ , m_buttons(0)
+ , m_motionTime(0)
+ , m_prevMotionTime(0)
+ , m_motionState(GHOST_kNotStarted)
+ , m_motionEventPending(false)
+ , m_deadZone(0.f)
{
- GHOST_NDOFLibraryInit_fp ndofLibraryInit = 0;
- GHOST_NDOFLibraryShutdown_fp ndofLibraryShutdown = 0;
- GHOST_NDOFDeviceOpen_fp ndofDeviceOpen = 0;
+ // to avoid the rare situation where one triple is updated and
+ // the other is not, initialize them both here:
+ memset(m_translation, 0, sizeof(m_translation));
+ memset(m_rotation, 0, sizeof(m_rotation));
}
-GHOST_NDOFManager::GHOST_NDOFManager()
+bool GHOST_NDOFManager::setDevice(unsigned short vendor_id, unsigned short product_id)
{
- m_DeviceHandle = 0;
+ // default to NDOF_UnknownDevice so rogue button events will get discarded
+ // "mystery device" owners can help build a HID_map for their hardware
+
+ switch (vendor_id) {
+ case 0x046D: // Logitech (3Dconnexion)
+ switch (product_id) {
+ // -- current devices --
+ case 0xC626:
+ puts("ndof: using SpaceNavigator");
+ m_deviceType = NDOF_SpaceNavigator;
+ m_buttonCount = 2;
+ break;
+ case 0xC628:
+ puts("ndof: using SpaceNavigator for Notebooks");
+ m_deviceType = NDOF_SpaceNavigator; // for Notebooks
+ m_buttonCount = 2;
+ break;
+ case 0xC627:
+ puts("ndof: using SpaceExplorer");
+ m_deviceType = NDOF_SpaceExplorer;
+ m_buttonCount = 15;
+ break;
+ case 0xC629:
+ puts("ndof: using SpacePilotPro");
+ m_deviceType = NDOF_SpacePilotPro;
+ m_buttonCount = 31;
+ break;
- // discover the API from the plugin
- ndofLibraryInit = 0;
- ndofLibraryShutdown = 0;
- ndofDeviceOpen = 0;
+ // -- older devices --
+ case 0xC625:
+ puts("ndof: using SpacePilot");
+ m_deviceType = NDOF_SpacePilot;
+ m_buttonCount = 21;
+ break;
+
+ case 0xC623:
+ puts("ndof: SpaceTraveler not supported, please file a bug report");
+ m_buttonCount = 8;
+ break;
+
+ default:
+ printf("ndof: unknown Logitech product %04hx\n", product_id);
+ }
+ break;
+ default:
+ printf("ndof: unknown device %04hx:%04hx\n", vendor_id, product_id);
+ }
+
+ if (m_deviceType == NDOF_UnknownDevice) {
+ return false;
+ }
+ else {
+ m_buttonMask = ~(-1 << m_buttonCount);
+
+#ifdef DEBUG_NDOF_BUTTONS
+ printf("ndof: %d buttons -> hex:%X\n", m_buttonCount, m_buttonMask);
+#endif
+
+ return true;
+ }
}
-GHOST_NDOFManager::~GHOST_NDOFManager()
+void GHOST_NDOFManager::updateTranslation(short t[3], GHOST_TUns64 time)
{
- if (ndofLibraryShutdown)
- ndofLibraryShutdown(m_DeviceHandle);
+ memcpy(m_translation, t, sizeof(m_translation));
+ m_motionTime = time;
+ m_motionEventPending = true;
+}
- m_DeviceHandle = 0;
+void GHOST_NDOFManager::updateRotation(short r[3], GHOST_TUns64 time)
+{
+ memcpy(m_rotation, r, sizeof(m_rotation));
+ m_motionTime = time;
+ m_motionEventPending = true;
+}
+
+void GHOST_NDOFManager::sendButtonEvent(NDOF_ButtonT button, bool press, GHOST_TUns64 time, GHOST_IWindow* window)
+{
+ GHOST_EventNDOFButton* event = new GHOST_EventNDOFButton(time, window);
+ GHOST_TEventNDOFButtonData* data = (GHOST_TEventNDOFButtonData*) event->getData();
+
+ data->action = press ? GHOST_kPress : GHOST_kRelease;
+ data->button = button;
+
+#ifdef DEBUG_NDOF_BUTTONS
+ printf("%s %s\n", ndof_button_names[button], press ? "pressed" : "released");
+#endif
+
+ m_system.pushEvent(event);
}
+void GHOST_NDOFManager::sendKeyEvent(GHOST_TKey key, bool press, GHOST_TUns64 time, GHOST_IWindow* window)
+{
+ GHOST_TEventType type = press ? GHOST_kEventKeyDown : GHOST_kEventKeyUp;
+ GHOST_EventKey* event = new GHOST_EventKey(time, type, window, key);
+
+#ifdef DEBUG_NDOF_BUTTONS
+ printf("keyboard %s\n", press ? "down" : "up");
+#endif
-int
-GHOST_NDOFManager::deviceOpen(GHOST_IWindow* window,
- GHOST_NDOFLibraryInit_fp setNdofLibraryInit,
- GHOST_NDOFLibraryShutdown_fp setNdofLibraryShutdown,
- GHOST_NDOFDeviceOpen_fp setNdofDeviceOpen)
+ m_system.pushEvent(event);
+}
+
+void GHOST_NDOFManager::updateButton(int button_number, bool press, GHOST_TUns64 time)
{
- int Pid;
-
- ndofLibraryInit = setNdofLibraryInit;
- ndofLibraryShutdown = setNdofLibraryShutdown;
- ndofDeviceOpen = setNdofDeviceOpen;
-
- if (ndofLibraryInit && ndofDeviceOpen)
- {
- Pid= ndofLibraryInit();
-#if 0
- printf("%i client \n", Pid);
+ GHOST_IWindow* window = m_system.getWindowManager()->getActiveWindow();
+
+#ifdef DEBUG_NDOF_BUTTONS
+ if (m_deviceType != NDOF_UnknownDevice)
+ printf("ndof: button %d -> ", button_number);
#endif
- #if defined(WITH_HEADLESS)
- /* do nothing */
- #elif defined(_WIN32) || defined(__APPLE__)
- m_DeviceHandle = ndofDeviceOpen((void *)&currentNdofValues);
- #elif defined(WITH_GHOST_SDL)
- /* do nothing */
- #else
- GHOST_SystemX11 *sys;
- sys = static_cast<GHOST_SystemX11*>(GHOST_ISystem::getSystem());
- void *ndofInfo = sys->prepareNdofInfo(&currentNdofValues);
- m_DeviceHandle = ndofDeviceOpen(ndofInfo);
- #endif
- return (Pid > 0) ? 0 : 1;
-
- } else
- return 1;
+
+ switch (m_deviceType) {
+ case NDOF_SpaceNavigator:
+ sendButtonEvent(SpaceNavigator_HID_map[button_number], press, time, window);
+ break;
+ case NDOF_SpaceExplorer:
+ switch (button_number) {
+ case 6: sendKeyEvent(GHOST_kKeyEsc, press, time, window); break;
+ case 7: sendKeyEvent(GHOST_kKeyLeftAlt, press, time, window); break;
+ case 8: sendKeyEvent(GHOST_kKeyLeftShift, press, time, window); break;
+ case 9: sendKeyEvent(GHOST_kKeyLeftControl, press, time, window); break;
+ default: sendButtonEvent(SpaceExplorer_HID_map[button_number], press, time, window);
+ }
+ break;
+ case NDOF_SpacePilotPro:
+ switch (button_number) {
+ case 22: sendKeyEvent(GHOST_kKeyEsc, press, time, window); break;
+ case 23: sendKeyEvent(GHOST_kKeyLeftAlt, press, time, window); break;
+ case 24: sendKeyEvent(GHOST_kKeyLeftShift, press, time, window); break;
+ case 25: sendKeyEvent(GHOST_kKeyLeftControl, press, time, window); break;
+ default: sendButtonEvent(SpacePilotPro_HID_map[button_number], press, time, window);
+ }
+ break;
+ case NDOF_SpacePilot:
+ switch (button_number) {
+ case 10: sendKeyEvent(GHOST_kKeyEsc, press, time, window); break;
+ case 11: sendKeyEvent(GHOST_kKeyLeftAlt, press, time, window); break;
+ case 12: sendKeyEvent(GHOST_kKeyLeftShift, press, time, window); break;
+ case 13: sendKeyEvent(GHOST_kKeyLeftControl, press, time, window); break;
+ case 20: puts("ndof: ignoring CONFIG button"); break;
+ default: sendButtonEvent(SpacePilot_HID_map[button_number], press, time, window);
+ }
+ break;
+ case NDOF_UnknownDevice:
+ printf("ndof: button %d on unknown device (ignoring)\n", button_number);
+ }
+
+ int mask = 1 << button_number;
+ if (press) {
+ m_buttons |= mask; // set this button's bit
+ }
+ else {
+ m_buttons &= ~mask; // clear this button's bit
+ }
}
+void GHOST_NDOFManager::updateButtons(int button_bits, GHOST_TUns64 time)
+{
+ button_bits &= m_buttonMask; // discard any "garbage" bits
+
+ int diff = m_buttons ^ button_bits;
-bool
-GHOST_NDOFManager::available() const
-{
- return m_DeviceHandle != 0;
+ for (int button_number = 0; button_number < m_buttonCount; ++button_number) {
+ int mask = 1 << button_number;
+
+ if (diff & mask) {
+ bool press = button_bits & mask;
+ updateButton(button_number, press, time);
+ }
+ }
}
-bool
-GHOST_NDOFManager::event_present() const
-{
- if( currentNdofValues.changed >0) {
- printf("time %llu but%u x%i y%i z%i rx%i ry%i rz%i \n" ,
- currentNdofValues.time, currentNdofValues.buttons,
- currentNdofValues.tx,currentNdofValues.ty,currentNdofValues.tz,
- currentNdofValues.rx,currentNdofValues.ry,currentNdofValues.rz);
- return true;
- }else
- return false;
+void GHOST_NDOFManager::setDeadZone(float dz)
+{
+ if (dz < 0.f) {
+ // negative values don't make sense, so clamp at zero
+ dz = 0.f;
+ }
+ else if (dz > 0.5f) {
+ // warn the rogue user/programmer, but allow it
+ printf("ndof: dead zone of %.2f is rather high...\n", dz);
+ }
+ m_deadZone = dz;
+ printf("ndof: dead zone set to %.2f\n", dz);
}
-void GHOST_NDOFManager::GHOST_NDOFGetDatas(GHOST_TEventNDOFData &datas) const
+static bool atHomePosition(GHOST_TEventNDOFMotionData* ndof)
{
- datas.tx = currentNdofValues.tx;
- datas.ty = currentNdofValues.ty;
- datas.tz = currentNdofValues.tz;
- datas.rx = currentNdofValues.rx;
- datas.ry = currentNdofValues.ry;
- datas.rz = currentNdofValues.rz;
- datas.buttons = currentNdofValues.buttons;
- datas.client = currentNdofValues.client;
- datas.address = currentNdofValues.address;
- datas.time = currentNdofValues.time;
- datas.delta = currentNdofValues.delta;
+#define HOME(foo) (ndof->foo == 0)
+ return HOME(tx) && HOME(ty) && HOME(tz) && HOME(rx) && HOME(ry) && HOME(rz);
+#undef HOME
+}
+
+static bool nearHomePosition(GHOST_TEventNDOFMotionData* ndof, float threshold)
+{
+ if (threshold == 0.f) {
+ return atHomePosition(ndof);
+ }
+ else {
+#define HOME1(foo) (fabsf(ndof->foo) < threshold)
+ return HOME1(tx) && HOME1(ty) && HOME1(tz) && HOME1(rx) && HOME1(ry) && HOME1(rz);
+#undef HOME1
+ }
+}
+
+bool GHOST_NDOFManager::sendMotionEvent()
+{
+ if (!m_motionEventPending)
+ return false;
+
+ m_motionEventPending = false; // any pending motion is handled right now
+
+ GHOST_IWindow* window = m_system.getWindowManager()->getActiveWindow();
+
+ if (window == NULL) {
+ return false; // delivery will fail, so don't bother sending
+ }
+
+ GHOST_EventNDOFMotion* event = new GHOST_EventNDOFMotion(m_motionTime, window);
+ GHOST_TEventNDOFMotionData* data = (GHOST_TEventNDOFMotionData*) event->getData();
+
+ // scale axis values here to normalize them to around +/- 1
+ // they are scaled again for overall sensitivity in the WM based on user prefs
+
+ const float scale = 1.f / 350.f; // 3Dconnexion devices send +/- 350 usually
+
+ data->tx = scale * m_translation[0];
+ data->ty = scale * m_translation[1];
+ data->tz = scale * m_translation[2];
+
+ data->rx = scale * m_rotation[0];
+ data->ry = scale * m_rotation[1];
+ data->rz = scale * m_rotation[2];
+
+ data->dt = 0.001f * (m_motionTime - m_prevMotionTime); // in seconds
+
+ bool handMotion = !nearHomePosition(data, m_deadZone);
+
+ // determine what kind of motion event to send (Starting, InProgress, Finishing)
+ // and where that leaves this NDOF manager (NotStarted, InProgress, Finished)
+ switch (m_motionState) {
+ case GHOST_kNotStarted:
+ case GHOST_kFinished:
+ if (handMotion) {
+ data->progress = GHOST_kStarting;
+ m_motionState = GHOST_kInProgress;
+ // prev motion time will be ancient, so just make up something reasonable
+ data->dt = 0.0125f;
+ }
+ else {
+ // send no event and keep current state
+ delete event;
+ return false;
+ }
+ break;
+ case GHOST_kInProgress:
+ if (handMotion) {
+ data->progress = GHOST_kInProgress;
+ // keep InProgress state
+ }
+ else {
+ data->progress = GHOST_kFinishing;
+ m_motionState = GHOST_kFinished;
+ }
+ break;
+ default:
+ break;
+ }
+
+#ifdef DEBUG_NDOF_MOTION
+ printf("ndof motion sent -- %s\n", progress_string[data->progress]);
+
+ // show details about this motion event
+ printf(" T=(%.2f,%.2f,%.2f) R=(%.2f,%.2f,%.2f) dt=%.3f\n",
+ data->tx, data->ty, data->tz,
+ data->rx, data->ry, data->rz,
+ data->dt);
+#endif
+
+ m_system.pushEvent(event);
+
+ m_prevMotionTime = m_motionTime;
+
+ return true;
}
diff --git a/intern/ghost/intern/GHOST_NDOFManager.h b/intern/ghost/intern/GHOST_NDOFManager.h
index c9e09370e09..5bdbe7a6833 100644
--- a/intern/ghost/intern/GHOST_NDOFManager.h
+++ b/intern/ghost/intern/GHOST_NDOFManager.h
@@ -1,4 +1,6 @@
/*
+ * $Id$
+ *
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
@@ -15,43 +17,144 @@
* 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): none yet.
+ * Contributor(s):
+ * Mike Erwin
*
* ***** END GPL LICENSE BLOCK *****
*/
-
-/** \file ghost/intern/GHOST_NDOFManager.h
- * \ingroup GHOST
- */
-
#ifndef _GHOST_NDOFMANAGER_H_
#define _GHOST_NDOFMANAGER_H_
#include "GHOST_System.h"
-#include "GHOST_IWindow.h"
+// #define DEBUG_NDOF_MOTION
+// #define DEBUG_NDOF_BUTTONS
+
+typedef enum {
+ NDOF_UnknownDevice, // <-- motion will work fine, buttons are ignored
+
+ // current devices
+ NDOF_SpaceNavigator,
+ NDOF_SpaceExplorer,
+ NDOF_SpacePilotPro,
+
+ // older devices
+ NDOF_SpacePilot
+
+ } NDOF_DeviceT;
+
+// NDOF device button event types
+typedef enum {
+ // used internally, never sent
+ NDOF_BUTTON_NONE,
+ // these two are available from any 3Dconnexion device
+ NDOF_BUTTON_MENU,
+ NDOF_BUTTON_FIT,
+ // standard views
+ NDOF_BUTTON_TOP,
+ NDOF_BUTTON_BOTTOM,
+ NDOF_BUTTON_LEFT,
+ NDOF_BUTTON_RIGHT,
+ NDOF_BUTTON_FRONT,
+ NDOF_BUTTON_BACK,
+ // more views
+ NDOF_BUTTON_ISO1,
+ NDOF_BUTTON_ISO2,
+ // 90 degree rotations
+ // these don't all correspond to physical buttons
+ NDOF_BUTTON_ROLL_CW,
+ NDOF_BUTTON_ROLL_CCW,
+ NDOF_BUTTON_SPIN_CW,
+ NDOF_BUTTON_SPIN_CCW,
+ NDOF_BUTTON_TILT_CW,
+ NDOF_BUTTON_TILT_CCW,
+ // device control
+ NDOF_BUTTON_ROTATE,
+ NDOF_BUTTON_PANZOOM,
+ NDOF_BUTTON_DOMINANT,
+ NDOF_BUTTON_PLUS,
+ NDOF_BUTTON_MINUS,
+ // general-purpose buttons
+ // users can assign functions via keymap editor
+ NDOF_BUTTON_1,
+ NDOF_BUTTON_2,
+ NDOF_BUTTON_3,
+ NDOF_BUTTON_4,
+ NDOF_BUTTON_5,
+ NDOF_BUTTON_6,
+ NDOF_BUTTON_7,
+ NDOF_BUTTON_8,
+ NDOF_BUTTON_9,
+ NDOF_BUTTON_10,
+
+ } NDOF_ButtonT;
class GHOST_NDOFManager
{
public:
- GHOST_NDOFManager();
- virtual ~GHOST_NDOFManager();
-
- int deviceOpen(GHOST_IWindow* window,
- GHOST_NDOFLibraryInit_fp setNdofLibraryInit,
- GHOST_NDOFLibraryShutdown_fp setNdofLibraryShutdown,
- GHOST_NDOFDeviceOpen_fp setNdofDeviceOpen);
-
- void GHOST_NDOFGetDatas(GHOST_TEventNDOFData &datas) const;
-
- bool available() const;
- bool event_present() const;
+ GHOST_NDOFManager(GHOST_System&);
+
+ virtual ~GHOST_NDOFManager() {};
+
+ // whether multi-axis functionality is available (via the OS or driver)
+ // does not imply that a device is plugged in or being used
+ virtual bool available() = 0;
+
+ // each platform's device detection should call this
+ // use standard USB/HID identifiers
+ bool setDevice(unsigned short vendor_id, unsigned short product_id);
+
+ // filter out small/accidental/uncalibrated motions by
+ // setting up a "dead zone" around home position
+ // set to 0 to disable
+ // 0.1 is a safe and reasonable value
+ void setDeadZone(float);
+
+ // the latest raw axis data from the device
+ // NOTE: axis data should be in blender view coordinates
+ // +X is to the right
+ // +Y is up
+ // +Z is out of the screen
+ // for rotations, look from origin to each +axis
+ // rotations are + when CCW, - when CW
+ // each platform is responsible for getting axis data into this form
+ // these values should not be scaled (just shuffled or flipped)
+ void updateTranslation(short t[3], GHOST_TUns64 time);
+ void updateRotation(short r[3], GHOST_TUns64 time);
+
+ // the latest raw button data from the device
+ // use HID button encoding (not NDOF_ButtonT)
+ void updateButton(int button_number, bool press, GHOST_TUns64 time);
+ void updateButtons(int button_bits, GHOST_TUns64 time);
+ // NDOFButton events are sent immediately
+
+ // processes and sends most recent raw data as an NDOFMotion event
+ // returns whether an event was sent
+ bool sendMotionEvent();
protected:
- void* m_DeviceHandle;
-};
+ GHOST_System& m_system;
+private:
+ void sendButtonEvent(NDOF_ButtonT, bool press, GHOST_TUns64 time, GHOST_IWindow*);
+ void sendKeyEvent(GHOST_TKey, bool press, GHOST_TUns64 time, GHOST_IWindow*);
+
+ NDOF_DeviceT m_deviceType;
+ int m_buttonCount;
+ int m_buttonMask;
+
+ short m_translation[3];
+ short m_rotation[3];
+ int m_buttons; // bit field
+
+ GHOST_TUns64 m_motionTime; // in milliseconds
+ GHOST_TUns64 m_prevMotionTime; // time of most recent Motion event sent
+
+ GHOST_TProgress m_motionState;
+ bool m_motionEventPending;
+ float m_deadZone; // discard motion with each component < this
+};
#endif
diff --git a/intern/ghost/intern/GHOST_NDOFManagerCocoa.h b/intern/ghost/intern/GHOST_NDOFManagerCocoa.h
new file mode 100644
index 00000000000..27397b711b7
--- /dev/null
+++ b/intern/ghost/intern/GHOST_NDOFManagerCocoa.h
@@ -0,0 +1,50 @@
+/*
+ * $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):
+ * Mike Erwin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef _GHOST_NDOFMANAGERCOCOA_H_
+#define _GHOST_NDOFMANAGERCOCOA_H_
+
+#include "GHOST_NDOFManager.h"
+
+// Event capture is handled within the NDOF manager on Macintosh,
+// so there's no need for SystemCocoa to look for them.
+
+class GHOST_NDOFManagerCocoa : public GHOST_NDOFManager
+{
+public:
+ GHOST_NDOFManagerCocoa(GHOST_System&);
+
+ ~GHOST_NDOFManagerCocoa();
+
+ // whether multi-axis functionality is available (via the OS or driver)
+ // does not imply that a device is plugged in or being used
+ bool available();
+
+private:
+ unsigned short m_clientID;
+};
+
+
+#endif
diff --git a/intern/ghost/intern/GHOST_NDOFManagerCocoa.mm b/intern/ghost/intern/GHOST_NDOFManagerCocoa.mm
new file mode 100644
index 00000000000..53a991a7396
--- /dev/null
+++ b/intern/ghost/intern/GHOST_NDOFManagerCocoa.mm
@@ -0,0 +1,172 @@
+/*
+ * $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):
+ * Mike Erwin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "GHOST_NDOFManagerCocoa.h"
+#include "GHOST_SystemCocoa.h"
+
+extern "C" {
+ #include <3DconnexionClient/ConnexionClientAPI.h>
+ #include <stdio.h>
+ }
+
+// static functions need to talk to these objects:
+static GHOST_SystemCocoa* ghost_system = NULL;
+static GHOST_NDOFManager* ndof_manager = NULL;
+
+// 3Dconnexion drivers before 10.x are "old"
+// not all buttons will work
+static bool has_old_driver = true;
+
+static void NDOF_DeviceAdded(io_connect_t connection)
+{
+ printf("ndof: device added\n"); // change these: printf --> informational reports
+
+#if 0 // device preferences will be useful some day
+ ConnexionDevicePrefs p;
+ ConnexionGetCurrentDevicePrefs(kDevID_AnyDevice, &p);
+#endif
+
+ // determine exactly which device is plugged in
+ SInt32 result = 0;
+ ConnexionControl(kConnexionCtlGetDeviceID, 0, &result);
+ unsigned short vendorID = result >> 16;
+ unsigned short productID = result & 0xffff;
+
+ ndof_manager->setDevice(vendorID, productID);
+}
+
+static void NDOF_DeviceRemoved(io_connect_t connection)
+{
+ printf("ndof: device removed\n");
+}
+
+static void NDOF_DeviceEvent(io_connect_t connection, natural_t messageType, void* messageArgument)
+{
+ switch (messageType)
+ {
+ case kConnexionMsgDeviceState:
+ {
+ ConnexionDeviceState* s = (ConnexionDeviceState*)messageArgument;
+
+ GHOST_TUns64 now = ghost_system->getMilliSeconds();
+
+ switch (s->command)
+ {
+ case kConnexionCmdHandleAxis:
+ {
+ // convert to blender view coordinates
+ short t[3] = {s->axis[0], -(s->axis[2]), s->axis[1]};
+ short r[3] = {-(s->axis[3]), s->axis[5], -(s->axis[4])};
+
+ ndof_manager->updateTranslation(t, now);
+ ndof_manager->updateRotation(r, now);
+
+ ghost_system->notifyExternalEventProcessed();
+ break;
+ }
+ case kConnexionCmdHandleButtons:
+ {
+ int button_bits = has_old_driver ? s->buttons8 : s->buttons;
+ ndof_manager->updateButtons(button_bits, now);
+ ghost_system->notifyExternalEventProcessed();
+ break;
+ }
+ case kConnexionCmdAppSpecific:
+ printf("ndof: app-specific command, param = %hd, value = %d\n", s->param, s->value);
+ break;
+
+ default:
+ printf("ndof: mystery device command %d\n", s->command);
+ }
+ break;
+ }
+ case kConnexionMsgPrefsChanged:
+ // printf("ndof: prefs changed\n"); // this includes app switches
+ // TODO: look through updated prefs for things blender cares about
+ break;
+ case kConnexionMsgCalibrateDevice:
+ printf("ndof: calibrate\n"); // but what should blender do?
+ break;
+ case kConnexionMsgDoMapping:
+ // printf("ndof: driver did something\n");
+ // sent when the driver itself consumes an NDOF event
+ // and performs whatever action is set in user prefs
+ // 3Dx header file says to ignore these
+ break;
+ default:
+ printf("ndof: mystery event %d\n", messageType);
+ }
+}
+
+GHOST_NDOFManagerCocoa::GHOST_NDOFManagerCocoa(GHOST_System& sys)
+ : GHOST_NDOFManager(sys)
+{
+ if (available())
+ {
+ // give static functions something to talk to:
+ ghost_system = dynamic_cast<GHOST_SystemCocoa*>(&sys);
+ ndof_manager = this;
+
+ OSErr error = InstallConnexionHandlers(NDOF_DeviceEvent, NDOF_DeviceAdded, NDOF_DeviceRemoved);
+ if (error) {
+ printf("ndof: error %d while installing handlers\n", error);
+ return;
+ }
+
+ // Pascal string *and* a four-letter constant. How old-skool.
+ m_clientID = RegisterConnexionClient('blnd', (UInt8*) "\007blender",
+ kConnexionClientModeTakeOver, kConnexionMaskAll);
+
+ // printf("ndof: client id = %d\n", m_clientID);
+
+ if (SetConnexionClientButtonMask != NULL) {
+ has_old_driver = false;
+ SetConnexionClientButtonMask(m_clientID, kConnexionMaskAllButtons);
+ }
+ else {
+ printf("ndof: old 3Dx driver installed, some buttons may not work\n");
+ }
+ }
+ else {
+ printf("ndof: 3Dx driver not found\n");
+ // This isn't a hard error, just means the user doesn't have a 3D mouse.
+ }
+}
+
+GHOST_NDOFManagerCocoa::~GHOST_NDOFManagerCocoa()
+{
+ UnregisterConnexionClient(m_clientID);
+ CleanupConnexionHandlers();
+ ghost_system = NULL;
+ ndof_manager = NULL;
+}
+
+bool GHOST_NDOFManagerCocoa::available()
+{
+ // extern OSErr InstallConnexionHandlers() __attribute__((weak_import));
+ // ^^ not needed since the entire framework is weak-linked
+ return InstallConnexionHandlers != NULL;
+ // this means that the driver is installed and dynamically linked to blender
+}
diff --git a/intern/ghost/intern/GHOST_NDOFManagerWin32.cpp b/intern/ghost/intern/GHOST_NDOFManagerWin32.cpp
new file mode 100644
index 00000000000..57d84ec14d4
--- /dev/null
+++ b/intern/ghost/intern/GHOST_NDOFManagerWin32.cpp
@@ -0,0 +1,41 @@
+/*
+ * $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):
+ * Mike Erwin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "GHOST_NDOFManagerWin32.h"
+
+
+GHOST_NDOFManagerWin32::GHOST_NDOFManagerWin32(GHOST_System& sys)
+ : GHOST_NDOFManager(sys)
+{
+ setDeadZone(0.1f);
+}
+
+// whether multi-axis functionality is available (via the OS or driver)
+// does not imply that a device is plugged in or being used
+bool GHOST_NDOFManagerWin32::available()
+{
+ // always available since RawInput is built into Windows
+ return true;
+}
diff --git a/intern/ghost/intern/GHOST_NDOFManagerWin32.h b/intern/ghost/intern/GHOST_NDOFManagerWin32.h
new file mode 100644
index 00000000000..31f7e074cd6
--- /dev/null
+++ b/intern/ghost/intern/GHOST_NDOFManagerWin32.h
@@ -0,0 +1,40 @@
+/*
+ * $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):
+ * Mike Erwin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef _GHOST_NDOFMANAGERWIN32_H_
+#define _GHOST_NDOFMANAGERWIN32_H_
+
+#include "GHOST_NDOFManager.h"
+
+
+class GHOST_NDOFManagerWin32 : public GHOST_NDOFManager
+{
+public:
+ GHOST_NDOFManagerWin32(GHOST_System&);
+ bool available();
+};
+
+
+#endif
diff --git a/intern/ghost/intern/GHOST_NDOFManagerX11.cpp b/intern/ghost/intern/GHOST_NDOFManagerX11.cpp
new file mode 100644
index 00000000000..099fa15d179
--- /dev/null
+++ b/intern/ghost/intern/GHOST_NDOFManagerX11.cpp
@@ -0,0 +1,106 @@
+/*
+ * $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):
+ * Mike Erwin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "GHOST_NDOFManagerX11.h"
+#include "GHOST_SystemX11.h"
+#include <spnav.h>
+#include <stdio.h>
+
+
+GHOST_NDOFManagerX11::GHOST_NDOFManagerX11(GHOST_System& sys)
+ :
+ GHOST_NDOFManager(sys),
+ m_available(false)
+{
+ setDeadZone(0.1f); // how to calibrate on Linux? throw away slight motion!
+
+ if (spnav_open() != -1) {
+ // determine exactly which device (if any) is plugged in
+
+#define MAX_LINE_LENGTH 100
+
+ // look for USB devices with Logitech's vendor ID
+ FILE* command_output = popen("lsusb -d 046d:","r");
+ if (command_output) {
+ char line[MAX_LINE_LENGTH] = {0};
+ while (fgets(line, MAX_LINE_LENGTH, command_output)) {
+ unsigned short vendor_id = 0, product_id = 0;
+ if (sscanf(line, "Bus %*d Device %*d: ID %hx:%hx", &vendor_id, &product_id) == 2)
+ if (setDevice(vendor_id, product_id)) {
+ m_available = true;
+ break; // stop looking once the first 3D mouse is found
+ }
+ }
+ pclose(command_output);
+ }
+ }
+ else {
+ printf("ndof: spacenavd not found\n");
+ // This isn't a hard error, just means the user doesn't have a 3D mouse.
+ }
+}
+
+GHOST_NDOFManagerX11::~GHOST_NDOFManagerX11()
+{
+ if (m_available)
+ spnav_close();
+}
+
+bool GHOST_NDOFManagerX11::available()
+{
+ return m_available;
+}
+
+//bool GHOST_NDOFManagerX11::identifyDevice()
+//{
+//
+//}
+
+bool GHOST_NDOFManagerX11::processEvents()
+{
+ GHOST_TUns64 now = m_system.getMilliSeconds();
+
+ bool anyProcessed = false;
+ spnav_event e;
+ while (spnav_poll_event(&e)) {
+ switch (e.type) {
+ case SPNAV_EVENT_MOTION:
+ {
+ // convert to blender view coords
+ short t[3] = {e.motion.x, e.motion.y, -e.motion.z};
+ short r[3] = {-e.motion.rx, -e.motion.ry, e.motion.rz};
+
+ updateTranslation(t, now);
+ updateRotation(r, now);
+ break;
+ }
+ case SPNAV_EVENT_BUTTON:
+ updateButton(e.button.bnum, e.button.press, now);
+ break;
+ }
+ anyProcessed = true;
+ }
+ return anyProcessed;
+}
diff --git a/intern/ghost/intern/GHOST_NDOFManagerX11.h b/intern/ghost/intern/GHOST_NDOFManagerX11.h
new file mode 100644
index 00000000000..82bd256c707
--- /dev/null
+++ b/intern/ghost/intern/GHOST_NDOFManagerX11.h
@@ -0,0 +1,49 @@
+/*
+ * $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):
+ * Mike Erwin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef _GHOST_NDOFMANAGERX11_H_
+#define _GHOST_NDOFMANAGERX11_H_
+
+#include "GHOST_NDOFManager.h"
+
+/* Event capture is handled within the NDOF manager on Linux,
+ * so there's no need for SystemX11 to look for them. */
+
+class GHOST_NDOFManagerX11 : public GHOST_NDOFManager
+{
+public:
+ GHOST_NDOFManagerX11(GHOST_System&);
+ ~GHOST_NDOFManagerX11();
+ bool available();
+ bool processEvents();
+
+private:
+ // bool identifyDevice();
+
+ bool m_available;
+};
+
+#endif
+
diff --git a/intern/ghost/intern/GHOST_System.cpp b/intern/ghost/intern/GHOST_System.cpp
index cb3e97fc574..64c2c218a07 100644
--- a/intern/ghost/intern/GHOST_System.cpp
+++ b/intern/ghost/intern/GHOST_System.cpp
@@ -46,7 +46,13 @@
GHOST_System::GHOST_System()
-: m_displayManager(0), m_timerManager(0), m_windowManager(0), m_eventManager(0), m_ndofManager(0)
+ : m_displayManager(0),
+ m_timerManager(0),
+ m_windowManager(0),
+ m_eventManager(0)
+#ifdef WITH_INPUT_NDOF
+ , m_ndofManager(0)
+#endif
{
}
@@ -194,12 +200,17 @@ bool GHOST_System::getFullScreen(void)
bool GHOST_System::dispatchEvents()
{
- bool handled;
- if (m_eventManager) {
- handled = m_eventManager->dispatchEvents();
+ bool handled = false;
+
+#ifdef WITH_INPUT_NDOF
+ // NDOF Motion event is sent only once per dispatch, so do it now:
+ if (m_ndofManager) {
+ handled |= m_ndofManager->sendMotionEvent();
}
- else {
- handled = false;
+#endif
+
+ if (m_eventManager) {
+ handled |= m_eventManager->dispatchEvents();
}
m_timerManager->fireTimers(getMilliSeconds());
@@ -243,18 +254,6 @@ GHOST_TSuccess GHOST_System::pushEvent(GHOST_IEvent* event)
return success;
}
-int GHOST_System::openNDOF(GHOST_IWindow* w,
- GHOST_NDOFLibraryInit_fp setNdofLibraryInit,
- GHOST_NDOFLibraryShutdown_fp setNdofLibraryShutdown,
- GHOST_NDOFDeviceOpen_fp setNdofDeviceOpen)
-{
- return m_ndofManager->deviceOpen(w,
- setNdofLibraryInit,
- setNdofLibraryShutdown,
- setNdofDeviceOpen);
-}
-
-
GHOST_TSuccess GHOST_System::getModifierKeyState(GHOST_TModifierKeyMask mask, bool& isDown) const
{
GHOST_ModifierKeys keys;
@@ -285,12 +284,6 @@ GHOST_TSuccess GHOST_System::init()
m_timerManager = new GHOST_TimerManager ();
m_windowManager = new GHOST_WindowManager ();
m_eventManager = new GHOST_EventManager ();
- m_ndofManager = new GHOST_NDOFManager();
-
-#if 0
- if(m_ndofManager)
- printf("ndof manager \n");
-#endif
#ifdef GHOST_DEBUG
if (m_eventManager) {
@@ -328,10 +321,12 @@ GHOST_TSuccess GHOST_System::exit()
delete m_eventManager;
m_eventManager = 0;
}
+#ifdef WITH_INPUT_NDOF
if (m_ndofManager) {
delete m_ndofManager;
m_ndofManager = 0;
}
+#endif
return GHOST_kSuccess;
}
diff --git a/intern/ghost/intern/GHOST_System.h b/intern/ghost/intern/GHOST_System.h
index b5c64bfceb6..c1e70916be6 100644
--- a/intern/ghost/intern/GHOST_System.h
+++ b/intern/ghost/intern/GHOST_System.h
@@ -191,25 +191,6 @@ public:
virtual GHOST_TSuccess removeEventConsumer(GHOST_IEventConsumer* consumer);
/***************************************************************************************
- ** N-degree of freedom devcice management functionality
- ***************************************************************************************/
-
- /** Inherited from GHOST_ISystem
- * Opens the N-degree of freedom device manager
- * return 0 if device found, 1 otherwise
- */
- virtual int openNDOF(GHOST_IWindow* w,
- GHOST_NDOFLibraryInit_fp setNdofLibraryInit,
- GHOST_NDOFLibraryShutdown_fp setNdofLibraryShutdown,
- GHOST_NDOFDeviceOpen_fp setNdofDeviceOpen);
-
-// original patch only
-// GHOST_NDOFEventHandler_fp setNdofEventHandler);
-
-
-
-
- /***************************************************************************************
** Cursor management functionality
***************************************************************************************/
@@ -268,11 +249,13 @@ public:
*/
virtual inline GHOST_WindowManager* getWindowManager() const;
+#ifdef WITH_INPUT_NDOF
/**
* Returns a pointer to our n-degree of freedeom manager.
* @return A pointer to our n-degree of freedeom manager.
*/
virtual inline GHOST_NDOFManager* getNDOFManager() const;
+#endif
/**
* Returns the state of all modifier keys.
@@ -337,8 +320,10 @@ protected:
/** The event manager. */
GHOST_EventManager* m_eventManager;
- /** The N-degree of freedom device manager */
- GHOST_NDOFManager* m_ndofManager;
+#ifdef WITH_INPUT_NDOF
+ /** The N-degree of freedom device manager */
+ GHOST_NDOFManager* m_ndofManager;
+#endif
/** Prints all the events. */
#ifdef GHOST_DEBUG
@@ -364,10 +349,12 @@ inline GHOST_WindowManager* GHOST_System::getWindowManager() const
return m_windowManager;
}
+#ifdef WITH_INPUT_NDOF
inline GHOST_NDOFManager* GHOST_System::getNDOFManager() const
{
return m_ndofManager;
}
+#endif
#endif // _GHOST_SYSTEM_H_
diff --git a/intern/ghost/intern/GHOST_SystemCocoa.h b/intern/ghost/intern/GHOST_SystemCocoa.h
index ce777358389..d20aed63f42 100644
--- a/intern/ghost/intern/GHOST_SystemCocoa.h
+++ b/intern/ghost/intern/GHOST_SystemCocoa.h
@@ -221,6 +221,11 @@ public:
GHOST_TSuccess handleApplicationBecomeActiveEvent();
/**
+ * External objects should call this when they send an event outside processEvents.
+ */
+ void notifyExternalEventProcessed();
+
+ /**
* @see GHOST_ISystem
*/
int toggleConsole(int action) { return 0; }
@@ -267,7 +272,7 @@ protected:
/** Start time at initialization. */
GHOST_TUns64 m_start_time;
- /** Event has been processed directly by Cocoa and has sent a ghost event to be dispatched */
+ /** Event has been processed directly by Cocoa (or NDOF manager) and has sent a ghost event to be dispatched */
bool m_outsideLoopEventProcessed;
/** Raised window is not yet known by the window manager, so delay application become active event handling */
diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm
index bb3d6e3aee3..17f0f2d6ecd 100644
--- a/intern/ghost/intern/GHOST_SystemCocoa.mm
+++ b/intern/ghost/intern/GHOST_SystemCocoa.mm
@@ -52,7 +52,7 @@
#include "GHOST_TimerTask.h"
#include "GHOST_WindowManager.h"
#include "GHOST_WindowCocoa.h"
-#include "GHOST_NDOFManager.h"
+#include "GHOST_NDOFManagerCocoa.h"
#include "AssertMacros.h"
#pragma mark KeyMap, mouse converters
@@ -596,6 +596,11 @@ GHOST_TSuccess GHOST_SystemCocoa::init()
GHOST_TSuccess success = GHOST_System::init();
if (success) {
+
+#ifdef WITH_INPUT_NDOF
+ m_ndofManager = new GHOST_NDOFManagerCocoa(*this);
+#endif
+
//ProcessSerialNumber psn;
//Carbon stuff to move window & menu to foreground
@@ -1007,6 +1012,11 @@ GHOST_TSuccess GHOST_SystemCocoa::handleApplicationBecomeActiveEvent()
return GHOST_kSuccess;
}
+void GHOST_SystemCocoa::notifyExternalEventProcessed()
+{
+ m_outsideLoopEventProcessed = true;
+}
+
//Note: called from NSWindow delegate
GHOST_TSuccess GHOST_SystemCocoa::handleWindowEvent(GHOST_TEventType eventType, GHOST_WindowCocoa* window)
{
@@ -1560,6 +1570,8 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
GHOST_TInt32 delta;
double deltaF = [event deltaY];
+
+ if (deltaF == 0.0) deltaF = [event deltaX]; // make blender decide if it's horizontal scroll
if (deltaF == 0.0) break; //discard trackpad delta=0 events
delta = deltaF > 0.0 ? 1 : -1;
diff --git a/intern/ghost/intern/GHOST_SystemPathsWin32.cpp b/intern/ghost/intern/GHOST_SystemPathsWin32.cpp
index becccc2c29f..523d119c7e7 100644
--- a/intern/ghost/intern/GHOST_SystemPathsWin32.cpp
+++ b/intern/ghost/intern/GHOST_SystemPathsWin32.cpp
@@ -32,12 +32,9 @@
#include "GHOST_SystemPathsWin32.h"
-#define WIN32_LEAN_AND_MEAN
-#ifdef _WIN32_IE
-#undef _WIN32_IE
-#endif
+#ifndef _WIN32_IE
#define _WIN32_IE 0x0501
-#include <windows.h>
+#endif
#include <shlobj.h>
#if defined(__MINGW32__) || defined(__CYGWIN__)
diff --git a/intern/ghost/intern/GHOST_SystemPathsWin32.h b/intern/ghost/intern/GHOST_SystemPathsWin32.h
index 67cc2140e0e..3de7bbf934e 100644
--- a/intern/ghost/intern/GHOST_SystemPathsWin32.h
+++ b/intern/ghost/intern/GHOST_SystemPathsWin32.h
@@ -38,6 +38,8 @@
#error WIN32 only!
#endif // WIN32
+#define _WIN32_WINNT 0x501 // require Windows XP or newer
+#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include "GHOST_SystemPaths.h"
diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp
index ace6cc0e0cf..bbf8efeaee3 100644
--- a/intern/ghost/intern/GHOST_SystemWin32.cpp
+++ b/intern/ghost/intern/GHOST_SystemWin32.cpp
@@ -39,22 +39,20 @@
* @date May 7, 2001
*/
+#ifdef BF_GHOST_DEBUG
#include <iostream>
-
-#ifdef FREE_WINDOWS
-# define WINVER 0x0501 /* GetConsoleWindow() for MinGW */
#endif
+#include <stdio.h> // [mce] temporary debug, remove soon!
+
#include "GHOST_SystemWin32.h"
#include "GHOST_EventDragnDrop.h"
-#define WIN32_LEAN_AND_MEAN
-#ifdef _WIN32_IE
-#undef _WIN32_IE
+#ifndef _WIN32_IE
+#define _WIN32_IE 0x0501 /* shipped before XP, so doesn't impose additional requirements */
#endif
-#define _WIN32_IE 0x0501
-#include <windows.h>
#include <shlobj.h>
+#include <tlhelp32.h>
// win64 doesn't define GWL_USERDATA
#ifdef WIN32
@@ -64,48 +62,17 @@
#endif
#endif
-/*
- * According to the docs the mouse wheel message is supported from windows 98
- * upwards. Leaving WINVER at default value, the WM_MOUSEWHEEL message and the
- * wheel detent value are undefined.
- */
-#ifndef WM_MOUSEWHEEL
-#define WM_MOUSEWHEEL 0x020A
-#endif // WM_MOUSEWHEEL
-#ifndef WHEEL_DELTA
-#define WHEEL_DELTA 120 /* Value for rolling one detent, (old convention! MS changed it) */
-#endif // WHEEL_DELTA
-
-/*
- * Defines for mouse buttons 4 and 5 aka xbutton1 and xbutton2.
- * MSDN: Declared in Winuser.h, include Windows.h
- * This does not seem to work with MinGW so we define our own here.
- */
-#ifndef XBUTTON1
-#define XBUTTON1 0x0001
-#endif // XBUTTON1
-#ifndef XBUTTON2
-#define XBUTTON2 0x0002
-#endif // XBUTTON2
-#ifndef WM_XBUTTONUP
-#define WM_XBUTTONUP 524
-#endif // WM_XBUTTONUP
-#ifndef WM_XBUTTONDOWN
-#define WM_XBUTTONDOWN 523
-#endif // WM_XBUTTONDOWN
-
#include "GHOST_Debug.h"
#include "GHOST_DisplayManagerWin32.h"
#include "GHOST_EventButton.h"
#include "GHOST_EventCursor.h"
#include "GHOST_EventKey.h"
#include "GHOST_EventWheel.h"
-#include "GHOST_EventNDOF.h"
#include "GHOST_TimerTask.h"
#include "GHOST_TimerManager.h"
#include "GHOST_WindowManager.h"
#include "GHOST_WindowWin32.h"
-#include "GHOST_NDOFManager.h"
+#include "GHOST_NDOFManagerWin32.h"
// Key code values not found in winuser.h
#ifndef VK_MINUS
@@ -158,18 +125,25 @@
#define VK_MEDIA_PLAY_PAUSE 0xB3
#endif // VK_MEDIA_PLAY_PAUSE
-/*
- Initiates WM_INPUT messages from keyboard
- That way GHOST can retrieve true keys
-*/
-GHOST_TInt32 GHOST_SystemWin32::initKeyboardRawInput(void)
+static void initRawInput()
{
- RAWINPUTDEVICE device = {0};
- device.usUsagePage = 0x01; /* usUsagePage & usUsage for keyboard*/
- device.usUsage = 0x06; /* http://msdn.microsoft.com/en-us/windows/hardware/gg487473.aspx */
+ RAWINPUTDEVICE devices[2];
+ memset(devices, 0, 2 * sizeof(RAWINPUTDEVICE));
+
+ // multi-axis mouse (SpaceNavigator, etc.)
+ devices[0].usUsagePage = 0x01;
+ devices[0].usUsage = 0x08;
- return RegisterRawInputDevices(&device, 1, sizeof(device));
-};
+ // Initiates WM_INPUT messages from keyboard
+ // That way GHOST can retrieve true keys
+ devices[1].usUsagePage = 0x01;
+ devices[1].usUsage = 0x06; /* http://msdn.microsoft.com/en-us/windows/hardware/gg487473.aspx */
+
+ if (RegisterRawInputDevices(devices, 2, sizeof(RAWINPUTDEVICE)))
+ puts("registered for RawInput (spacenav & keyboard)");
+ else
+ printf("could not register for RawInput: %d\n", (int)GetLastError());
+}
GHOST_SystemWin32::GHOST_SystemWin32()
: m_hasPerformanceCounter(false), m_freq(0), m_start(0)
@@ -186,6 +160,10 @@ GHOST_SystemWin32::GHOST_SystemWin32()
this->handleKeyboardChange();
// Require COM for GHOST_DropTargetWin32 created in GHOST_WindowWin32.
OleInitialize(0);
+
+#ifdef WITH_INPUT_NDOF
+ m_ndofManager = new GHOST_NDOFManagerWin32(*this);
+#endif
}
GHOST_SystemWin32::~GHOST_SystemWin32()
@@ -244,6 +222,7 @@ GHOST_IWindow* GHOST_SystemWin32::createWindow(
// Store the pointer to the window
// if (state != GHOST_kWindowStateFullScreen) {
m_windowManager->addWindow(window);
+ m_windowManager->setActiveWindow(window);
// }
}
else {
@@ -384,22 +363,15 @@ GHOST_TSuccess GHOST_SystemWin32::init()
GHOST_TSuccess success = GHOST_System::init();
/* Disable scaling on high DPI displays on Vista */
+ HMODULE
user32 = ::LoadLibraryA("user32.dll");
typedef BOOL (WINAPI * LPFNSETPROCESSDPIAWARE)();
LPFNSETPROCESSDPIAWARE SetProcessDPIAware =
(LPFNSETPROCESSDPIAWARE)GetProcAddress(user32, "SetProcessDPIAware");
if (SetProcessDPIAware)
SetProcessDPIAware();
- #ifdef NEED_RAW_PROC
- pRegisterRawInputDevices = (LPFNDLLRRID)GetProcAddress(user32, "RegisterRawInputDevices");
- pGetRawInputData = (LPFNDLLGRID)GetProcAddress(user32, "GetRawInputData");
- #else
- FreeLibrary(user32);
- #endif
-
- /* Initiates WM_INPUT messages from keyboard */
- initKeyboardRawInput();
-
+ FreeLibrary(user32);
+ initRawInput();
// Determine whether this system has a high frequency performance counter. */
m_hasPerformanceCounter = ::QueryPerformanceFrequency((LARGE_INTEGER*)&m_freq) == TRUE;
@@ -440,104 +412,84 @@ GHOST_TSuccess GHOST_SystemWin32::init()
GHOST_TSuccess GHOST_SystemWin32::exit()
{
- #ifdef NEED_RAW_PROC
- FreeLibrary(user32);
- #endif
-
return GHOST_System::exit();
}
-GHOST_TKey GHOST_SystemWin32::hardKey(GHOST_IWindow *window, WPARAM wParam, LPARAM lParam, int * keyDown, char * vk)
+GHOST_TKey GHOST_SystemWin32::hardKey(GHOST_IWindow *window, RAWINPUT const& raw, int * keyDown, char * vk)
{
- unsigned int size = 0;
- char * data;
GHOST_TKey key = GHOST_kKeyUnknown;
if(!keyDown)
return GHOST_kKeyUnknown;
- GetRawInputData((HRAWINPUT)lParam, RID_INPUT, 0, &size, sizeof(RAWINPUTHEADER));
+ GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem();
- if((data = (char*)malloc(size)) &&
- GetRawInputData((HRAWINPUT)lParam, RID_INPUT, data, &size, sizeof(RAWINPUTHEADER)))
+ GHOST_ModifierKeys modifiers;
+ system->retrieveModifierKeys(modifiers);
+
+ *keyDown = !(raw.data.keyboard.Flags & RI_KEY_BREAK);
+ key = this->convertKey(window, raw.data.keyboard.VKey, raw.data.keyboard.MakeCode, (raw.data.keyboard.Flags&(RI_KEY_E1|RI_KEY_E0)));
+
+ // extra handling of modifier keys: don't send repeats out from GHOST
+ if(key >= GHOST_kKeyLeftShift && key <= GHOST_kKeyRightAlt)
{
- RAWINPUT ri;
- memcpy(&ri,data,(size < sizeof(ri)) ? size : sizeof(ri));
-
- if (ri.header.dwType == RIM_TYPEKEYBOARD)
- {
- GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem();
-
- GHOST_ModifierKeys modifiers;
- system->retrieveModifierKeys(modifiers);
-
- *keyDown = !(ri.data.keyboard.Flags & RI_KEY_BREAK);
- key = this->convertKey(window, ri.data.keyboard.VKey, ri.data.keyboard.MakeCode, (ri.data.keyboard.Flags&(RI_KEY_E1|RI_KEY_E0)));
-
- // extra handling of modifier keys: don't send repeats out from GHOST
- if(key >= GHOST_kKeyLeftShift && key <= GHOST_kKeyRightAlt)
- {
- bool changed = false;
- GHOST_TModifierKeyMask modifier;
- switch(key) {
- case GHOST_kKeyLeftShift:
- {
- changed = (modifiers.get(GHOST_kModifierKeyLeftShift) != (bool)*keyDown);
- modifier = GHOST_kModifierKeyLeftShift;
- }
- break;
- case GHOST_kKeyRightShift:
- {
- changed = (modifiers.get(GHOST_kModifierKeyRightShift) != (bool)*keyDown);
- modifier = GHOST_kModifierKeyRightShift;
- }
- break;
- case GHOST_kKeyLeftControl:
- {
- changed = (modifiers.get(GHOST_kModifierKeyLeftControl) != (bool)*keyDown);
- modifier = GHOST_kModifierKeyLeftControl;
- }
- break;
- case GHOST_kKeyRightControl:
- {
- changed = (modifiers.get(GHOST_kModifierKeyRightControl) != (bool)*keyDown);
- modifier = GHOST_kModifierKeyRightControl;
- }
- break;
- case GHOST_kKeyLeftAlt:
- {
- changed = (modifiers.get(GHOST_kModifierKeyLeftAlt) != (bool)*keyDown);
- modifier = GHOST_kModifierKeyLeftAlt;
- }
- break;
- case GHOST_kKeyRightAlt:
- {
- changed = (modifiers.get(GHOST_kModifierKeyRightAlt) != (bool)*keyDown);
- modifier = GHOST_kModifierKeyRightAlt;
- }
- break;
- default: break;
+ bool changed = false;
+ GHOST_TModifierKeyMask modifier;
+ switch(key) {
+ case GHOST_kKeyLeftShift:
+ {
+ changed = (modifiers.get(GHOST_kModifierKeyLeftShift) != (bool)*keyDown);
+ modifier = GHOST_kModifierKeyLeftShift;
}
-
- if(changed)
+ break;
+ case GHOST_kKeyRightShift:
{
- modifiers.set(modifier, (bool)*keyDown);
- system->storeModifierKeys(modifiers);
+ changed = (modifiers.get(GHOST_kModifierKeyRightShift) != (bool)*keyDown);
+ modifier = GHOST_kModifierKeyRightShift;
}
- else
+ break;
+ case GHOST_kKeyLeftControl:
{
- key = GHOST_kKeyUnknown;
+ changed = (modifiers.get(GHOST_kModifierKeyLeftControl) != (bool)*keyDown);
+ modifier = GHOST_kModifierKeyLeftControl;
}
- }
-
+ break;
+ case GHOST_kKeyRightControl:
+ {
+ changed = (modifiers.get(GHOST_kModifierKeyRightControl) != (bool)*keyDown);
+ modifier = GHOST_kModifierKeyRightControl;
+ }
+ break;
+ case GHOST_kKeyLeftAlt:
+ {
+ changed = (modifiers.get(GHOST_kModifierKeyLeftAlt) != (bool)*keyDown);
+ modifier = GHOST_kModifierKeyLeftAlt;
+ }
+ break;
+ case GHOST_kKeyRightAlt:
+ {
+ changed = (modifiers.get(GHOST_kModifierKeyRightAlt) != (bool)*keyDown);
+ modifier = GHOST_kModifierKeyRightAlt;
+ }
+ break;
+ default: break;
+ }
+
+ if(changed)
+ {
+ modifiers.set(modifier, (bool)*keyDown);
+ system->storeModifierKeys(modifiers);
+ }
+ else
+ {
+ key = GHOST_kKeyUnknown;
+ }
+ }
- if(vk) *vk = ri.data.keyboard.VKey;
- };
- };
- free(data);
+ if(vk) *vk = raw.data.keyboard.VKey;
return key;
}
@@ -741,12 +693,12 @@ GHOST_EventWheel* GHOST_SystemWin32::processWheelEvent(GHOST_IWindow *window, WP
}
-GHOST_EventKey* GHOST_SystemWin32::processKeyEvent(GHOST_IWindow *window, WPARAM wParam, LPARAM lParam)
+GHOST_EventKey* GHOST_SystemWin32::processKeyEvent(GHOST_IWindow *window, RAWINPUT const& raw)
{
int keyDown=0;
char vk;
GHOST_SystemWin32 * system = (GHOST_SystemWin32 *)getSystem();
- GHOST_TKey key = system->hardKey(window, wParam, lParam, &keyDown, &vk);
+ GHOST_TKey key = system->hardKey(window, raw, &keyDown, &vk);
GHOST_EventKey* event;
if (key != GHOST_kKeyUnknown) {
char ascii = '\0';
@@ -776,7 +728,13 @@ GHOST_EventKey* GHOST_SystemWin32::processKeyEvent(GHOST_IWindow *window, WPARAM
GHOST_Event* GHOST_SystemWin32::processWindowEvent(GHOST_TEventType type, GHOST_IWindow* window)
{
- return new GHOST_Event(getSystem()->getMilliSeconds(), type, window);
+ GHOST_System* system = (GHOST_System*)getSystem();
+
+ if (type == GHOST_kEventWindowActivate) {
+ system->getWindowManager()->setActiveWindow(window);
+ }
+
+ return new GHOST_Event(system->getMilliSeconds(), type, window);
}
GHOST_TSuccess GHOST_SystemWin32::pushDragDropEvent(GHOST_TEventType eventType,
@@ -799,9 +757,102 @@ void GHOST_SystemWin32::processMinMaxInfo(MINMAXINFO * minmax)
minmax->ptMinTrackSize.y=240;
}
+#ifdef WITH_INPUT_NDOF
+bool GHOST_SystemWin32::processNDOF(RAWINPUT const& raw)
+{
+ bool eventSent = false;
+ GHOST_TUns64 now = getMilliSeconds();
+
+ static bool firstEvent = true;
+ if (firstEvent) { // determine exactly which device is plugged in
+ RID_DEVICE_INFO info;
+ unsigned infoSize = sizeof(RID_DEVICE_INFO);
+ info.cbSize = infoSize;
+
+ GetRawInputDeviceInfo(raw.header.hDevice, RIDI_DEVICEINFO, &info, &infoSize);
+ if (info.dwType == RIM_TYPEHID)
+ m_ndofManager->setDevice(info.hid.dwVendorId, info.hid.dwProductId);
+ else
+ puts("<!> not a HID device... mouse/kb perhaps?");
+
+ firstEvent = false;
+ }
+
+ // The NDOF manager sends button changes immediately, and *pretends* to
+ // send motion. Mark as 'sent' so motion will always get dispatched.
+ eventSent = true;
+
+#ifdef _MSC_VER
+ // using Microsoft compiler & header files
+ // they invented the RawInput API, so this version is (probably) correct
+ BYTE const* data = raw.data.hid.bRawData;
+ // struct RAWHID {
+ // DWORD dwSizeHid;
+ // DWORD dwCount;
+ // BYTE bRawData[1];
+ // };
+#else
+ // MinGW's definition (below) doesn't agree, so we need a slight
+ // workaround until it's fixed
+ BYTE const* data = &raw.data.hid.bRawData;
+ // struct RAWHID {
+ // DWORD dwSizeHid;
+ // DWORD dwCount;
+ // BYTE bRawData; // <== isn't this s'posed to be a BYTE*?
+ // };
+#endif
+
+ BYTE packetType = data[0];
+ switch (packetType)
+ {
+ case 1: // translation
+ {
+ short* axis = (short*)(data + 1);
+ short t[3] = {axis[0], -axis[2], axis[1]};
+ m_ndofManager->updateTranslation(t, now);
+
+ if (raw.data.hid.dwSizeHid == 13)
+ { // this report also includes rotation
+ short r[3] = {-axis[3], axis[5], -axis[4]};
+ m_ndofManager->updateRotation(r, now);
+
+ // I've never gotten one of these, has anyone else?
+ puts("ndof: combined T + R");
+ }
+ break;
+ }
+ case 2: // rotation
+ {
+ short* axis = (short*)(data + 1);
+ short r[3] = {-axis[0], axis[2], -axis[1]};
+ m_ndofManager->updateRotation(r, now);
+ break;
+ }
+ case 3: // buttons
+ {
+#if 0
+ // I'm getting garbage bits -- examine whole report:
+ printf("ndof: HID report for buttons [");
+ for (int i = 0; i < raw.data.hid.dwSizeHid; ++i)
+ printf(" %02X", data[i]);
+ printf(" ]\n");
+#endif
+
+ int button_bits;
+ memcpy(&button_bits, data + 1, sizeof(button_bits));
+ m_ndofManager->updateButtons(button_bits, now);
+ break;
+ }
+ }
+ return eventSent;
+}
+#endif // WITH_INPUT_NDOF
+
LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
GHOST_Event* event = 0;
+ bool eventHandled = false;
+
LRESULT lResult = 0;
GHOST_SystemWin32* system = ((GHOST_SystemWin32*)getSystem());
GHOST_ASSERT(system, "GHOST_SystemWin32::s_wndProc(): system not initialized")
@@ -818,18 +869,38 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
// Keyboard events, processed
////////////////////////////////////////////////////////////////////////
case WM_INPUT:
+ {
// check WM_INPUT from input sink when ghost window is not in the foreground
if (wParam == RIM_INPUTSINK) {
if (GetFocus() != hwnd) // WM_INPUT message not for this window
return 0;
- } //else wPAram == RIM_INPUT
- event = processKeyEvent(window, wParam, lParam);
- if (!event) {
- GHOST_PRINT("GHOST_SystemWin32::wndProc: key event ")
- GHOST_PRINT(msg)
- GHOST_PRINT(" key ignored\n")
+ } //else wParam == RIM_INPUT
+
+ RAWINPUT raw;
+ RAWINPUT* raw_ptr = &raw;
+ UINT rawSize = sizeof(RAWINPUT);
+
+ GetRawInputData((HRAWINPUT)lParam, RID_INPUT, raw_ptr, &rawSize, sizeof(RAWINPUTHEADER));
+
+ switch (raw.header.dwType)
+ {
+ case RIM_TYPEKEYBOARD:
+ event = processKeyEvent(window, raw);
+ if (!event) {
+ GHOST_PRINT("GHOST_SystemWin32::wndProc: key event ")
+ GHOST_PRINT(msg)
+ GHOST_PRINT(" key ignored\n")
+ }
+ break;
+ case RIM_TYPEHID:
+#ifdef WITH_INPUT_NDOF
+ if (system->processNDOF(raw))
+ eventHandled = true;
+#endif
+ break;
}
- break;
+ break;
+ }
////////////////////////////////////////////////////////////////////////
// Keyboard events, ignored
////////////////////////////////////////////////////////////////////////
@@ -839,9 +910,9 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
case WM_SYSKEYUP:
/* These functions were replaced by WM_INPUT*/
case WM_CHAR:
- /* The WM_CHAR message is posted to the window with the keyboard focus when
- * a WM_KEYDOWN message is translated by the TranslateMessage function. WM_CHAR
- * contains the character code of the key that was pressed.
+ /* The WM_CHAR message is posted to the window with the keyboard focus when
+ * a WM_KEYDOWN message is translated by the TranslateMessage function. WM_CHAR
+ * contains the character code of the key that was pressed.
*/
case WM_DEADCHAR:
/* The WM_DEADCHAR message is posted to the window with the keyboard focus when a
@@ -989,11 +1060,16 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
* procedure of the top-level window being activated. If the windows use different input queues,
* the message is sent asynchronously, so the window is activated immediately.
*/
+ {
+ GHOST_ModifierKeys modifiers;
+ modifiers.clear();
+ system->storeModifierKeys(modifiers);
event = processWindowEvent(LOWORD(wParam) ? GHOST_kEventWindowActivate : GHOST_kEventWindowDeactivate, window);
/* WARNING: Let DefWindowProc handle WM_ACTIVATE, otherwise WM_MOUSEWHEEL
will not be dispatched to OUR active window if we minimize one of OUR windows. */
lResult = ::DefWindowProc(hwnd, msg, wParam, lParam);
break;
+ }
case WM_PAINT:
/* An application sends the WM_PAINT message when the system or another application
* makes a request to paint a portion of an application's window. The message is sent
@@ -1122,28 +1198,6 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
* In GHOST, we let DefWindowProc call the timer callback.
*/
break;
- case WM_BLND_NDOF_AXIS:
- {
- GHOST_TEventNDOFData ndofdata;
- system->m_ndofManager->GHOST_NDOFGetDatas(ndofdata);
- system->m_eventManager->
- pushEvent(new GHOST_EventNDOF(
- system->getMilliSeconds(),
- GHOST_kEventNDOFMotion,
- window, ndofdata));
- }
- break;
- case WM_BLND_NDOF_BTN:
- {
- GHOST_TEventNDOFData ndofdata;
- system->m_ndofManager->GHOST_NDOFGetDatas(ndofdata);
- system->m_eventManager->
- pushEvent(new GHOST_EventNDOF(
- system->getMilliSeconds(),
- GHOST_kEventNDOFButton,
- window, ndofdata));
- }
- break;
}
}
else {
@@ -1165,10 +1219,12 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
if (event) {
system->pushEvent(event);
+ eventHandled = true;
}
- else {
+
+ if (!eventHandled)
lResult = ::DefWindowProc(hwnd, msg, wParam, lParam);
- }
+
return lResult;
}
@@ -1237,8 +1293,32 @@ int GHOST_SystemWin32::toggleConsole(int action)
{
case 3: //hide if no console
{
- CONSOLE_SCREEN_BUFFER_INFO csbi = {{0}};
- if(!GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi) || csbi.dwCursorPosition.X || csbi.dwCursorPosition.Y>1)
+ DWORD sp = GetCurrentProcessId();
+ HANDLE ptree = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
+ PROCESSENTRY32 e = {0}; e.dwSize = sizeof(PROCESSENTRY32);
+
+ if( Process32First(ptree, &e)) {
+ do { //Searches for Blender's PROCESSENTRY32
+ if (e.th32ProcessID == sp) {
+ sp = e.th32ParentProcessID;
+ Process32First(ptree, &e);
+ do { //Got parent id, searches for its PROCESSENTRY32
+ if (e.th32ProcessID == sp) {
+ if(strcmp("explorer.exe",e.szExeFile)==0)
+ { //If explorer, hide cmd
+ ShowWindow(GetConsoleWindow(),SW_HIDE);
+ m_consoleStatus = 0;
+ }
+ break;
+ }
+
+ } while( Process32Next(ptree, &e));
+ break;
+ }
+ } while( Process32Next(ptree, &e));
+ }
+
+ CloseHandle(ptree);
break;
}
case 0: //hide
diff --git a/intern/ghost/intern/GHOST_SystemWin32.h b/intern/ghost/intern/GHOST_SystemWin32.h
index 729ad56d875..c5dff27dace 100644
--- a/intern/ghost/intern/GHOST_SystemWin32.h
+++ b/intern/ghost/intern/GHOST_SystemWin32.h
@@ -38,7 +38,10 @@
#error WIN32 only!
#endif // WIN32
+#define _WIN32_WINNT 0x501 // require Windows XP or newer
+#define WIN32_LEAN_AND_MEAN
#include <windows.h>
+#include <ole2.h> // for drag-n-drop
#include "GHOST_System.h"
@@ -46,95 +49,6 @@
# define __int64 long long
#endif
-#ifndef WM_INPUT
-#define WM_INPUT 0x00FF
-#endif
-#ifndef RID_INPUT
-#define RID_INPUT 0x10000003
-#endif
-#ifndef RIM_INPUTSINK
-#define RIM_INPUTSINK 0x1
-#endif
-#ifndef RI_KEY_BREAK
-#define RI_KEY_BREAK 0x1
-#endif
-#ifndef RI_KEY_E0
-#define RI_KEY_E0 0x2
-#endif
-#ifndef RI_KEY_E1
-#define RI_KEY_E1 0x4
-#endif
-#ifndef RIM_TYPEMOUSE
-#define RIM_TYPEMOUSE 0x0
-#define RIM_TYPEKEYBOARD 0x1
-#define RIM_TYPEHID 0x2
-
-typedef struct tagRAWINPUTDEVICE {
- USHORT usUsagePage;
- USHORT usUsage;
- DWORD dwFlags;
- HWND hwndTarget;
-} RAWINPUTDEVICE;
-
-
-
-typedef struct tagRAWINPUTHEADER {
- DWORD dwType;
- DWORD dwSize;
- HANDLE hDevice;
- WPARAM wParam;
-} RAWINPUTHEADER;
-
-typedef struct tagRAWMOUSE {
- USHORT usFlags;
- union {
- ULONG ulButtons;
- struct {
- USHORT usButtonFlags;
- USHORT usButtonData;
- };
- };
- ULONG ulRawButtons;
- LONG lLastX;
- LONG lLastY;
- ULONG ulExtraInformation;
-} RAWMOUSE;
-
-typedef struct tagRAWKEYBOARD {
- USHORT MakeCode;
- USHORT Flags;
- USHORT Reserved;
- USHORT VKey;
- UINT Message;
- ULONG ExtraInformation;
-} RAWKEYBOARD;
-
-typedef struct tagRAWHID {
- DWORD dwSizeHid;
- DWORD dwCount;
- BYTE bRawData[1];
-} RAWHID;
-
-typedef struct tagRAWINPUT {
- RAWINPUTHEADER header;
- union {
- RAWMOUSE mouse;
- RAWKEYBOARD keyboard;
- RAWHID hid;
- } data;
-} RAWINPUT;
-
-DECLARE_HANDLE(HRAWINPUT);
-#endif
-
-#ifdef FREE_WINDOWS
-#define NEED_RAW_PROC
-typedef BOOL (WINAPI * LPFNDLLRRID)(RAWINPUTDEVICE*,UINT, UINT);
-
-typedef UINT (WINAPI * LPFNDLLGRID)(HRAWINPUT, UINT, LPVOID, PUINT, UINT);
-#define GetRawInputData(hRawInput, uiCommand, pData, pcbSize, cbSizeHeader) ((pGetRawInputData)?pGetRawInputData(hRawInput, uiCommand, pData, pcbSize, cbSizeHeader):(UINT)-1)
-#endif
-
class GHOST_EventButton;
class GHOST_EventCursor;
class GHOST_EventKey;
@@ -314,14 +228,13 @@ protected:
/**
* Catches raw WIN32 key codes from WM_INPUT in the wndproc.
- * @param window-> The window for this handling
- * @param wParam The wParam from the wndproc
- * @param lParam The lParam from the wndproc
+ * @param window The window for this handling
+ * @param raw RawInput structure with detailed info about the key event
* @param keyDown Pointer flag that specify if a key is down
* @param vk Pointer to virtual key
* @return The GHOST key (GHOST_kKeyUnknown if no match).
*/
- virtual GHOST_TKey hardKey(GHOST_IWindow *window, WPARAM wParam, LPARAM lParam, int * keyDown, char * vk);
+ virtual GHOST_TKey hardKey(GHOST_IWindow *window, RAWINPUT const& raw, int * keyDown, char * vk);
/**
* Creates modifier key event(s) and updates the key data stored locally (m_modifierKeys).
@@ -362,10 +275,9 @@ protected:
* In most cases this is a straightforward conversion of key codes.
* For the modifier keys however, we want to distinguish left and right keys.
* @param window The window receiving the event (the active window).
- * @param wParam The wParam from the wndproc
- * @param lParam The lParam from the wndproc
+ * @param raw RawInput structure with detailed info about the key event
*/
- static GHOST_EventKey* processKeyEvent(GHOST_IWindow *window, WPARAM wParam, LPARAM lParam);
+ static GHOST_EventKey* processKeyEvent(GHOST_IWindow *window, RAWINPUT const& raw);
/**
* Process special keys (VK_OEM_*), to see if current key layout
@@ -383,12 +295,22 @@ protected:
* @return The event created.
*/
static GHOST_Event* processWindowEvent(GHOST_TEventType type, GHOST_IWindow* window);
- /**
+
+ /**
* Handles minimum window size.
* @param minmax The MINMAXINFO structure.
*/
static void processMinMaxInfo(MINMAXINFO * minmax);
-
+
+ /**
+ * Handles Motion and Button events from a SpaceNavigator or related device.
+ * Instead of returning an event object, this function communicates directly
+ * with the GHOST_NDOFManager.
+ * @param raw RawInput structure with detailed info about the NDOF event
+ * @return Whether an event was generated and sent.
+ */
+ bool processNDOF(RAWINPUT const& raw);
+
/**
* Returns the local state of the modifier keys (from the message queue).
* @param keys The state of the keys.
@@ -413,11 +335,6 @@ protected:
static LRESULT WINAPI s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
/**
- * Initiates WM_INPUT messages from keyboard
- */
- GHOST_TInt32 initKeyboardRawInput(void);
-
- /**
* Toggles console
* @action 0 - Hides
* 1 - Shows
@@ -445,15 +362,6 @@ protected:
/** Console status */
int m_consoleStatus;
-
- /** handle for user32.dll*/
- HMODULE user32;
- #ifdef NEED_RAW_PROC
- /* pointer to RegisterRawInputDevices function */
- LPFNDLLRRID pRegisterRawInputDevices;
- /* pointer to GetRawInputData function */
- LPFNDLLGRID pGetRawInputData;
- #endif
};
inline void GHOST_SystemWin32::retrieveModifierKeys(GHOST_ModifierKeys& keys) const
@@ -487,4 +395,3 @@ inline void GHOST_SystemWin32::handleKeyboardChange(void)
}
}
#endif // _GHOST_SYSTEM_WIN32_H_
-
diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp
index dd296fa979c..105f71b514f 100644
--- a/intern/ghost/intern/GHOST_SystemX11.cpp
+++ b/intern/ghost/intern/GHOST_SystemX11.cpp
@@ -42,8 +42,7 @@
#include "GHOST_EventKey.h"
#include "GHOST_EventButton.h"
#include "GHOST_EventWheel.h"
-#include "GHOST_EventNDOF.h"
-#include "GHOST_NDOFManager.h"
+#include "GHOST_NDOFManagerX11.h"
#include "GHOST_DisplayManagerX11.h"
#include "GHOST_Debug.h"
@@ -79,19 +78,6 @@
static GHOST_TKey
convertXKey(KeySym key);
-typedef struct NDOFPlatformInfo {
- Display *display;
- Window window;
- volatile GHOST_TEventNDOFData *currValues;
- Atom cmdAtom;
- Atom motionAtom;
- Atom btnPressAtom;
- Atom btnRelAtom;
-} NDOFPlatformInfo;
-
-static NDOFPlatformInfo sNdofInfo = {NULL, 0, NULL, 0, 0, 0, 0};
-
-
//these are for copy and select copy
static char *txt_cut_buffer= NULL;
static char *txt_select_buffer= NULL;
@@ -181,6 +167,9 @@ init(
GHOST_TSuccess success = GHOST_System::init();
if (success) {
+#ifdef WITH_INPUT_NDOF
+ m_ndofManager = new GHOST_NDOFManagerX11(*this);
+#endif
m_displayManager = new GHOST_DisplayManagerX11(this);
if (m_displayManager) {
@@ -275,7 +264,7 @@ createWindow(
if (window->getValid()) {
// Store the pointer to the window
m_windowManager->addWindow(window);
-
+ m_windowManager->setActiveWindow(window);
pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window) );
}
else {
@@ -386,8 +375,6 @@ lastEventTime(Time default_time) {
return data.timestamp;
}
-
-
bool
GHOST_SystemX11::
processEvents(
@@ -428,6 +415,13 @@ processEvents(
if (generateWindowExposeEvents()) {
anyProcessed = true;
}
+
+#ifdef WITH_INPUT_NDOF
+ if (dynamic_cast<GHOST_NDOFManagerX11*>(m_ndofManager)->processEvents()) {
+ anyProcessed = true;
+ }
+#endif
+
} while (waitForEvent && !anyProcessed);
return anyProcessed;
@@ -611,6 +605,9 @@ GHOST_SystemX11::processEvent(XEvent *xe)
case FocusOut:
{
XFocusChangeEvent &xfe = xe->xfocus;
+
+ // TODO: make sure this is the correct place for activate/deactivate
+ // printf("X: focus %s for window %d\n", xfe.type == FocusIn ? "in" : "out", (int) xfe.window);
// May have to look at the type of event and filter some
// out.
@@ -641,32 +638,8 @@ GHOST_SystemX11::processEvent(XEvent *xe)
);
} else
#endif
- if (sNdofInfo.currValues) {
- static GHOST_TEventNDOFData data = {0,0,0,0,0,0,0,0,0,0,0};
- if (xcme.message_type == sNdofInfo.motionAtom)
- {
- data.changed = 1;
- data.delta = xcme.data.s[8] - data.time;
- data.time = xcme.data.s[8];
- data.tx = xcme.data.s[2] >> 2;
- data.ty = xcme.data.s[3] >> 2;
- data.tz = xcme.data.s[4] >> 2;
- data.rx = xcme.data.s[5];
- data.ry = xcme.data.s[6];
- data.rz =-xcme.data.s[7];
- g_event = new GHOST_EventNDOF(getMilliSeconds(),
- GHOST_kEventNDOFMotion,
- window, data);
- } else if (xcme.message_type == sNdofInfo.btnPressAtom) {
- data.changed = 2;
- data.delta = xcme.data.s[8] - data.time;
- data.time = xcme.data.s[8];
- data.buttons = xcme.data.s[2];
- g_event = new GHOST_EventNDOF(getMilliSeconds(),
- GHOST_kEventNDOFButton,
- window, data);
- }
- } else if (((Atom)xcme.data.l[0]) == m_wm_take_focus) {
+
+ if (((Atom)xcme.data.l[0]) == m_wm_take_focus) {
XWindowAttributes attr;
Window fwin;
int revert_to;
@@ -723,6 +696,14 @@ GHOST_SystemX11::processEvent(XEvent *xe)
xce.y_root
);
}
+
+ // printf("X: %s window %d\n", xce.type == EnterNotify ? "entering" : "leaving", (int) xce.window);
+
+ if (xce.type == EnterNotify)
+ m_windowManager->setActiveWindow(window);
+ else
+ m_windowManager->setWindowInactive(window);
+
break;
}
case MapNotify:
@@ -834,6 +815,8 @@ GHOST_SystemX11::processEvent(XEvent *xe)
}
}
+#if 0 // obsolete SpaceNav code
+
void *
GHOST_SystemX11::
prepareNdofInfo(volatile GHOST_TEventNDOFData *currentNdofValues)
@@ -846,6 +829,8 @@ prepareNdofInfo(volatile GHOST_TEventNDOFData *currentNdofValues)
return (void*)&sNdofInfo;
}
+#endif
+
GHOST_TSuccess
GHOST_SystemX11::
getModifierKeys(
diff --git a/intern/ghost/intern/GHOST_SystemX11.h b/intern/ghost/intern/GHOST_SystemX11.h
index 746cd4ebdf4..845243f92e5 100644
--- a/intern/ghost/intern/GHOST_SystemX11.h
+++ b/intern/ghost/intern/GHOST_SystemX11.h
@@ -203,11 +203,6 @@ public:
return m_display;
}
- void *
- prepareNdofInfo(
- volatile GHOST_TEventNDOFData *current_values
- );
-
/* Helped function for get data from the clipboard. */
void getClipboard_xcout(XEvent evt, Atom sel, Atom target,
unsigned char **txt, unsigned long *len,
diff --git a/intern/ghost/intern/GHOST_TaskbarWin32.h b/intern/ghost/intern/GHOST_TaskbarWin32.h
index ef9ebdf5860..eddff8bb91b 100644
--- a/intern/ghost/intern/GHOST_TaskbarWin32.h
+++ b/intern/ghost/intern/GHOST_TaskbarWin32.h
@@ -3,20 +3,16 @@
*/
#ifndef GHOST_TASKBARWIN32_H_
#define GHOST_TASKBARWIN32_H_
+
#ifndef WIN32
#error WIN32 only!
#endif // WIN32
+#define _WIN32_WINNT 0x501 // require Windows XP or newer
+#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <shlobj.h>
-/* MinGW needs it */
-#ifdef FREE_WINDOWS
-#ifdef WINVER
-#undef WINVER
-#endif
-#define WINVER 0x0501
-#endif /* FREE_WINDOWS */
// ITaskbarList, ITaskbarList2 and ITaskbarList3 might be missing, present here in that case.
// Note, ITaskbarList3 is supported only since Windows 7, though. Check for that is done in
diff --git a/intern/ghost/intern/GHOST_WindowWin32.h b/intern/ghost/intern/GHOST_WindowWin32.h
index 4055c3acf56..70914d9d2ef 100644
--- a/intern/ghost/intern/GHOST_WindowWin32.h
+++ b/intern/ghost/intern/GHOST_WindowWin32.h
@@ -39,19 +39,11 @@
#endif // WIN32
#include "GHOST_Window.h"
+#include "GHOST_TaskbarWin32.h"
-/* MinGW needs it */
-#ifdef FREE_WINDOWS
-#ifdef WINVER
-#undef WINVER
-#endif
-#define WINVER 0x0501
-#endif
-
-
-
+#define _WIN32_WINNT 0x501 // require Windows XP or newer
+#define WIN32_LEAN_AND_MEAN
#include <windows.h>
-#include "GHOST_TaskbarWin32.h"
#include <wintab.h>
diff --git a/release/scripts/modules/addon_utils.py b/release/scripts/modules/addon_utils.py
index cf74282d064..22936f4c209 100644
--- a/release/scripts/modules/addon_utils.py
+++ b/release/scripts/modules/addon_utils.py
@@ -16,7 +16,7 @@
#
# ##### END GPL LICENSE BLOCK #####
-# <pep8 compliant>
+# <pep8-80 compliant>
__all__ = (
"paths",
@@ -26,13 +26,14 @@ __all__ = (
"disable",
"reset_all",
"module_bl_info",
-)
+ )
import bpy as _bpy
error_duplicates = False
+
def paths():
# RELEASE SCRIPTS: official scripts distributed in Blender releases
paths = _bpy.utils.script_paths("addons")
@@ -128,7 +129,12 @@ def modules(module_cache):
error_duplicates = True
elif mod.__time__ != os.path.getmtime(mod_path):
- print("reloading addon:", mod_name, mod.__time__, os.path.getmtime(mod_path), mod_path)
+ print("reloading addon:",
+ mod_name,
+ mod.__time__,
+ os.path.getmtime(mod_path),
+ mod_path,
+ )
del module_cache[mod_name]
mod = None
@@ -143,7 +149,9 @@ def modules(module_cache):
del modules_stale
mod_list = list(module_cache.values())
- mod_list.sort(key=lambda mod: (mod.bl_info['category'], mod.bl_info['name']))
+ mod_list.sort(key=lambda mod: (mod.bl_info['category'],
+ mod.bl_info['name'],
+ ))
return mod_list
@@ -163,8 +171,9 @@ def check(module_name):
loaded_state = mod and getattr(mod, "__addon_enabled__", Ellipsis)
if loaded_state is Ellipsis:
- print("Warning: addon-module %r found module but without"
- " __addon_enabled__ field, possible name collision from file: %r" %
+ print("Warning: addon-module %r found module "
+ "but without __addon_enabled__ field, "
+ "possible name collision from file: %r" %
(module_name, getattr(mod, "__file__", "<unknown>")))
loaded_state = False
@@ -207,7 +216,8 @@ def enable(module_name, default_set=True):
return None
mod.__addon_enabled__ = False
- # Split registering up into 3 steps so we can undo if it fails par way through
+ # Split registering up into 3 steps so we can undo
+ # if it fails par way through.
# 1) try import
try:
mod = __import__(module_name)
@@ -254,8 +264,9 @@ def disable(module_name, default_set=True):
import sys
mod = sys.modules.get(module_name)
- # possible this addon is from a previous session and didnt load a module this time.
- # so even if the module is not found, still disable the addon in the user prefs.
+ # possible this addon is from a previous session and didnt load a
+ # module this time. So even if the module is not found, still disable
+ # the addon in the user prefs.
if mod:
mod.__addon_enabled__ = False
@@ -310,7 +321,22 @@ def reset_all(reload_scripts=False):
disable(mod_name)
-def module_bl_info(mod, info_basis={"name": "", "author": "", "version": (), "blender": (), "api": 0, "location": "", "description": "", "wiki_url": "", "tracker_url": "", "support": 'COMMUNITY', "category": "", "warning": "", "show_expanded": False}):
+def module_bl_info(mod, info_basis={"name": "",
+ "author": "",
+ "version": (),
+ "blender": (),
+ "api": 0,
+ "location": "",
+ "description": "",
+ "wiki_url": "",
+ "tracker_url": "",
+ "support": 'COMMUNITY',
+ "category": "",
+ "warning": "",
+ "show_expanded": False,
+ }
+ ):
+
addon_info = getattr(mod, "bl_info", {})
# avoid re-initializing
diff --git a/release/scripts/modules/bpy/__init__.py b/release/scripts/modules/bpy/__init__.py
index 9c48dc89f83..a43b42e49a1 100644
--- a/release/scripts/modules/bpy/__init__.py
+++ b/release/scripts/modules/bpy/__init__.py
@@ -16,7 +16,7 @@
#
# ##### END GPL LICENSE BLOCK #####
-# <pep8 compliant>
+# <pep8-80 compliant>
"""
Give access to blender data and utility functions.
@@ -31,7 +31,7 @@ __all__ = (
"props",
"types",
"utils",
-)
+ )
# internal blender C module
@@ -43,12 +43,14 @@ from . import utils, path, ops
# fake operator module
ops = ops.ops_fake_module
+
def _main():
import sys as _sys
# Possibly temp. addons path
from os.path import join, dirname, normpath
- _sys.path.append(normpath(join(dirname(__file__), "..", "..", "addons", "modules")))
+ _sys.path.append(normpath(join(dirname(__file__),
+ "..", "..", "addons", "modules")))
# if "-d" in sys.argv: # Enable this to measure startup speed
if 0:
diff --git a/release/scripts/modules/bpy/path.py b/release/scripts/modules/bpy/path.py
index f6254efac2e..284fef97795 100644
--- a/release/scripts/modules/bpy/path.py
+++ b/release/scripts/modules/bpy/path.py
@@ -16,26 +16,44 @@
#
# ##### END GPL LICENSE BLOCK #####
-# <pep8 compliant>
+# <pep8-80 compliant>
"""
This module has a similar scope to os.path, containing utility
functions for dealing with paths in Blender.
"""
+__all__ = (
+ "abspath",
+ "basename",
+ "clean_name",
+ "display_name",
+ "display_name_from_filepath",
+ "ensure_ext",
+ "is_subdir",
+ "module_names",
+ "relpath",
+ "resolve_ncase",
+ )
+
import bpy as _bpy
import os as _os
def abspath(path, start=None):
"""
- Returns the absolute path relative to the current blend file using the "//" prefix.
+ Returns the absolute path relative to the current blend file
+ using the "//" prefix.
- :arg start: Relative to this path, when not set the current filename is used.
+ :arg start: Relative to this path,
+ when not set the current filename is used.
:type start: string
"""
if path.startswith("//"):
- return _os.path.join(_os.path.dirname(_bpy.data.filepath) if start is None else start, path[2:])
+ return _os.path.join(_os.path.dirname(_bpy.data.filepath)
+ if start is None else start,
+ path[2:],
+ )
return path
@@ -44,7 +62,8 @@ def relpath(path, start=None):
"""
Returns the path relative to the current blend file using the "//" prefix.
- :arg start: Relative to this path, when not set the current filename is used.
+ :arg start: Relative to this path,
+ when not set the current filename is used.
:type start: string
"""
if not path.startswith("//"):
@@ -68,27 +87,28 @@ def is_subdir(path, directory):
def clean_name(name, replace="_"):
"""
- Returns a name with characters replaced that may cause problems under various circumstances, such as writing to a file.
+ Returns a name with characters replaced that
+ may cause problems under various circumstances,
+ such as writing to a file.
All characters besides A-Z/a-z, 0-9 are replaced with "_"
or the replace argument if defined.
"""
- unclean_chars = \
- "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\
- \x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\
- \x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\
- \x2e\x2f\x3a\x3b\x3c\x3d\x3e\x3f\x40\x5b\x5c\x5d\x5e\x60\x7b\
- \x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\
- \x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\
- \x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\
- \xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\
- \xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\
- \xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\
- \xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\
- \xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\
- \xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe"
-
- for ch in unclean_chars:
+ bad_chars = ("\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e"
+ "\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d"
+ "\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c"
+ "\x2e\x2f\x3a\x3b\x3c\x3d\x3e\x3f\x40\x5b\x5c\x5d\x5e\x60\x7b"
+ "\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a"
+ "\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99"
+ "\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8"
+ "\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7"
+ "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6"
+ "\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5"
+ "\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4"
+ "\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3"
+ "\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe")
+
+ for ch in bad_chars:
name = name.replace(ch, replace)
return name
@@ -96,8 +116,9 @@ def clean_name(name, replace="_"):
def display_name(name):
"""
Creates a display string from name to be used menus and the user interface.
- Capitalize the first letter in all lowercase names, mixed case names are kept as is.
- Intended for use with filenames and module names.
+ Capitalize the first letter in all lowercase names,
+ mixed case names are kept as is. Intended for use with
+ filenames and module names.
"""
name_base = _os.path.splitext(name)[0]
@@ -115,9 +136,11 @@ def display_name(name):
def display_name_from_filepath(name):
"""
- Returns the path stripped of directort and extension, ensured to be utf8 compatible.
+ Returns the path stripped of directory and extension,
+ ensured to be utf8 compatible.
"""
- return _os.path.splitext(basename(name))[0].encode("utf8", "replace").decode("utf8")
+ name = _os.path.splitext(basename(name))[0]
+ return name.encode("utf8", "replace").decode("utf8")
def resolve_ncase(path):
@@ -132,7 +155,8 @@ def resolve_ncase(path):
if not path or os.path.exists(path):
return path, True
- filename = os.path.basename(path) # filename may be a directory or a file
+ # filename may be a directory or a file
+ filename = os.path.basename(path)
dirpath = os.path.dirname(path)
suffix = path[:0] # "" but ensure byte/str match
@@ -180,7 +204,7 @@ def resolve_ncase(path):
def ensure_ext(filepath, ext, case_sensitive=False):
"""
- Return the path with the extension added its its not alredy set.
+ Return the path with the extension added if it is not already set.
:arg ext: The extension to check for.
:type ext: string
@@ -190,7 +214,9 @@ def ensure_ext(filepath, ext, case_sensitive=False):
import os
fn_base, fn_ext = os.path.splitext(filepath)
if fn_base and fn_ext:
- if (case_sensitive and ext == fn_ext) or (ext.lower() == fn_ext.lower()):
+ if ((case_sensitive and ext == fn_ext) or
+ (ext.lower() == fn_ext.lower())):
+
return filepath
else:
return fn_base + ext
@@ -228,7 +254,9 @@ def module_names(path, recursive=False):
modules.append((filename, fullpath))
if recursive:
for mod_name, mod_path in module_names(directory, True):
- modules.append(("%s.%s" % (filename, mod_name), mod_path))
+ modules.append(("%s.%s" % (filename, mod_name),
+ mod_path,
+ ))
return modules
@@ -239,4 +267,4 @@ def basename(path):
Use for Windows compatibility.
"""
- return _os.path.basename(path[2:] if path.startswith("//") else path)
+ return _os.path.basename(path[2:] if path[:2] in {"//", b"//"} else path)
diff --git a/release/scripts/modules/bpy/utils.py b/release/scripts/modules/bpy/utils.py
index 57d3e6dd703..a6304378cc4 100644
--- a/release/scripts/modules/bpy/utils.py
+++ b/release/scripts/modules/bpy/utils.py
@@ -16,13 +16,33 @@
#
# ##### END GPL LICENSE BLOCK #####
-# <pep8 compliant>
+# <pep8-80 compliant>
"""
This module contains utility functions specific to blender but
not assosiated with blenders internal data.
"""
+__all__ = (
+ "blend_paths",
+ "keyconfig_set",
+ "load_scripts",
+ "modules_from_path",
+ "preset_find",
+ "preset_paths",
+ "refresh_script_paths",
+ "register_class",
+ "register_module",
+ "resource_path",
+ "script_paths",
+ "smpte_from_frame",
+ "smpte_from_seconds",
+ "unregister_class",
+ "unregister_module",
+ "user_resource",
+ "user_script_path",
+ )
+
from _bpy import register_class, unregister_class, blend_paths, resource_path
from _bpy import script_paths as _bpy_script_paths
from _bpy import user_resource as _user_resource
@@ -42,7 +62,8 @@ def _test_import(module_name, loaded_modules):
if module_name in loaded_modules:
return None
if "." in module_name:
- print("Ignoring '%s', can't import files containing multiple periods." % module_name)
+ print("Ignoring '%s', can't import files containing "
+ "multiple periods." % module_name)
return None
if use_time:
@@ -74,7 +95,8 @@ def modules_from_path(path, loaded_modules):
:arg path: this path is scanned for scripts and packages.
:type path: string
- :arg loaded_modules: already loaded module names, files matching these names will be ignored.
+ :arg loaded_modules: already loaded module names, files matching these
+ names will be ignored.
:type loaded_modules: set
:return: all loaded modules.
:rtype: list
@@ -97,13 +119,17 @@ def load_scripts(reload_scripts=False, refresh_scripts=False):
"""
Load scripts and run each modules register function.
- :arg reload_scripts: Causes all scripts to have their unregister method called before loading.
+ :arg reload_scripts: Causes all scripts to have their unregister method
+ called before loading.
:type reload_scripts: bool
- :arg refresh_scripts: only load scripts which are not already loaded as modules.
+ :arg refresh_scripts: only load scripts which are not already loaded
+ as modules.
:type refresh_scripts: bool
"""
use_time = _bpy.app.debug
+ prefs = _bpy.context.user_preferences
+
if use_time:
import time
t_main = time.time()
@@ -116,10 +142,11 @@ def load_scripts(reload_scripts=False, refresh_scripts=False):
if reload_scripts:
_bpy_types.TypeMap.clear()
- # just unload, dont change user defaults, this means we can sync to reload.
- # note that they will only actually reload of the modification time changes.
- # this `wont` work for packages so... its not perfect.
- for module_name in [ext.module for ext in _bpy.context.user_preferences.addons]:
+ # just unload, dont change user defaults, this means we can sync
+ # to reload. note that they will only actually reload of the
+ # modification time changes. This `wont` work for packages so...
+ # its not perfect.
+ for module_name in [ext.module for ext in prefs.addons]:
_addon_utils.disable(module_name, default_set=False)
def register_module_call(mod):
@@ -131,7 +158,9 @@ def load_scripts(reload_scripts=False, refresh_scripts=False):
import traceback
traceback.print_exc()
else:
- print("\nWarning! '%s' has no register function, this is now a requirement for registerable scripts." % mod.__file__)
+ print("\nWarning! '%s' has no register function, "
+ "this is now a requirement for registerable scripts." %
+ mod.__file__)
def unregister_module_call(mod):
unregister = getattr(mod, "unregister", None)
@@ -172,7 +201,8 @@ def load_scripts(reload_scripts=False, refresh_scripts=False):
if reload_scripts:
# module names -> modules
- _global_loaded_modules[:] = [_sys.modules[mod_name] for mod_name in _global_loaded_modules]
+ _global_loaded_modules[:] = [_sys.modules[mod_name]
+ for mod_name in _global_loaded_modules]
# loop over and unload all scripts
_global_loaded_modules.reverse()
@@ -201,7 +231,8 @@ def load_scripts(reload_scripts=False, refresh_scripts=False):
_addon_utils.reset_all(reload_scripts)
# run the active integration preset
- filepath = preset_find(_bpy.context.user_preferences.inputs.active_keyconfig, "keyconfig")
+ filepath = preset_find(prefs.inputs.active_keyconfig, "keyconfig")
+
if filepath:
keyconfig_set(filepath)
@@ -214,12 +245,16 @@ def load_scripts(reload_scripts=False, refresh_scripts=False):
# base scripts
-_scripts = _os.path.join(_os.path.dirname(__file__), _os.path.pardir, _os.path.pardir)
+_scripts = _os.path.join(_os.path.dirname(__file__),
+ _os.path.pardir,
+ _os.path.pardir,
+ )
_scripts = (_os.path.normpath(_scripts), )
def user_script_path():
- path = _bpy.context.user_preferences.filepaths.script_directory
+ prefs = _bpy.context.user_preferences
+ path = prefs.filepaths.script_directory
if path:
path = _os.path.normpath(path)
@@ -236,22 +271,25 @@ def script_paths(subdir=None, user_pref=True, all=False):
:type subdir: string
:arg user_pref: Include the user preference script path.
:type user_pref: bool
- :arg all: Include local, user and system paths rather just the paths blender uses.
+ :arg all: Include local, user and system paths rather just the paths
+ blender uses.
:type all: bool
:return: script paths.
:rtype: list
"""
scripts = list(_scripts)
+ prefs = _bpy.context.user_preferences
# add user scripts dir
if user_pref:
- user_script_path = _bpy.context.user_preferences.filepaths.script_directory
+ user_script_path = prefs.filepaths.script_directory
else:
user_script_path = None
if all:
# all possible paths
- base_paths = tuple(_os.path.join(resource_path(res), "scripts") for res in ('LOCAL', 'USER', 'SYSTEM'))
+ base_paths = tuple(_os.path.join(resource_path(res), "scripts")
+ for res in ('LOCAL', 'USER', 'SYSTEM'))
else:
# only paths blender uses
base_paths = _bpy_script_paths()
@@ -426,7 +464,8 @@ def user_resource(type, path="", create=False):
:type type: string
:arg subdir: Optional subdirectory.
:type subdir: string
- :arg create: Treat the path as a directory and create it if its not existing.
+ :arg create: Treat the path as a directory and create
+ it if its not existing.
:type create: boolean
:return: a path.
:rtype: string
@@ -477,7 +516,8 @@ def register_module(module, verbose=False):
try:
register_class(cls)
except:
- print("bpy.utils.register_module(): failed to registering class %r" % cls)
+ print("bpy.utils.register_module(): "
+ "failed to registering class %r" % cls)
import traceback
traceback.print_exc()
if verbose:
@@ -495,7 +535,8 @@ def unregister_module(module, verbose=False):
try:
unregister_class(cls)
except:
- print("bpy.utils.unregister_module(): failed to unregistering class %r" % cls)
+ print("bpy.utils.unregister_module(): "
+ "failed to unregistering class %r" % cls)
import traceback
traceback.print_exc()
if verbose:
diff --git a/release/scripts/modules/bpy_extras/__init__.py b/release/scripts/modules/bpy_extras/__init__.py
index 06d41fa670e..d853d5fda10 100644
--- a/release/scripts/modules/bpy_extras/__init__.py
+++ b/release/scripts/modules/bpy_extras/__init__.py
@@ -16,7 +16,7 @@
#
# ##### END GPL LICENSE BLOCK #####
-# <pep8 compliant>
+# <pep8-80 compliant>
"""
Utility modules assosiated with the bpy module.
@@ -28,4 +28,4 @@ __all__ = (
"image_utils",
"mesh_utils",
"view3d_utils",
-)
+ )
diff --git a/release/scripts/modules/bpy_extras/image_utils.py b/release/scripts/modules/bpy_extras/image_utils.py
index e56c1c651c4..eab75c3bd16 100644
--- a/release/scripts/modules/bpy_extras/image_utils.py
+++ b/release/scripts/modules/bpy_extras/image_utils.py
@@ -16,11 +16,11 @@
#
# ##### END GPL LICENSE BLOCK #####
-# <pep8 compliant>
+# <pep8-80 compliant>
__all__ = (
"load_image",
-)
+ )
# limited replacement for BPyImage.comprehensiveImageLoad
@@ -33,8 +33,8 @@ def load_image(imagepath,
verbose=False,
):
"""
- Return an image from the file path with options to search multiple paths and
- return a placeholder if its not found.
+ Return an image from the file path with options to search multiple paths
+ and return a placeholder if its not found.
:arg filepath: The image filename
If a path precedes it, this will be searched as well.
@@ -51,9 +51,10 @@ def load_image(imagepath,
:type recursive: bool
:arg ncase_cmp: on non windows systems, find the correct case for the file.
:type ncase_cmp: bool
- :arg convert_callback: a function that takes an existing path and returns a new one.
- Use this when loading image formats blender may not support, the CONVERT_CALLBACK
- can take the path for a GIF (for example), convert it to a PNG and return the PNG's path.
+ :arg convert_callback: a function that takes an existing path and returns
+ a new one. Use this when loading image formats blender may not support,
+ the CONVERT_CALLBACK can take the path for a GIF (for example),
+ convert it to a PNG and return the PNG's path.
For formats blender can read, simply return the path that is given.
:type convert_callback: function
:return: an image or None
@@ -92,7 +93,9 @@ def load_image(imagepath,
for filepath_test in variants:
if ncase_cmp:
- ncase_variants = filepath_test, bpy.path.resolve_ncase(filepath_test)
+ ncase_variants = (filepath_test,
+ bpy.path.resolve_ncase(filepath_test),
+ )
else:
ncase_variants = (filepath_test, )
diff --git a/release/scripts/modules/bpy_extras/io_utils.py b/release/scripts/modules/bpy_extras/io_utils.py
index 9545e20b025..45664384efa 100644
--- a/release/scripts/modules/bpy_extras/io_utils.py
+++ b/release/scripts/modules/bpy_extras/io_utils.py
@@ -16,7 +16,7 @@
#
# ##### END GPL LICENSE BLOCK #####
-# <pep8 compliant>
+# <pep8-80 compliant>
__all__ = (
"ExportHelper",
@@ -31,15 +31,34 @@ __all__ = (
"path_reference_copy",
"path_reference_mode",
"unique_name"
-)
+ )
import bpy
from bpy.props import StringProperty, BoolProperty, EnumProperty
+def _check_axis_conversion(op):
+ if hasattr(op, "axis_forward") and hasattr(op, "axis_up"):
+ return axis_conversion_ensure(op,
+ "axis_forward",
+ "axis_up",
+ )
+ return False
+
+
class ExportHelper:
- filepath = StringProperty(name="File Path", description="Filepath used for exporting the file", maxlen=1024, default="", subtype='FILE_PATH')
- check_existing = BoolProperty(name="Check Existing", description="Check and warn on overwriting existing files", default=True, options={'HIDDEN'})
+ filepath = StringProperty(
+ name="File Path",
+ description="Filepath used for exporting the file",
+ maxlen=1024,
+ subtype='FILE_PATH',
+ )
+ check_existing = BoolProperty(
+ name="Check Existing",
+ description="Check and warn on overwriting existing files",
+ default=True,
+ options={'HIDDEN'},
+ )
# subclasses can override with decorator
# True == use ext, False == no ext, None == do nothing.
@@ -60,27 +79,39 @@ class ExportHelper:
return {'RUNNING_MODAL'}
def check(self, context):
- check_extension = self.check_extension
+ change_ext = False
+ change_axis = _check_axis_conversion(self)
- if check_extension is None:
- return False
+ check_extension = self.check_extension
- filepath = bpy.path.ensure_ext(self.filepath, self.filename_ext if check_extension else "")
+ if check_extension is not None:
+ filepath = bpy.path.ensure_ext(self.filepath,
+ self.filename_ext
+ if check_extension
+ else "")
- if filepath != self.filepath:
- self.filepath = filepath
- return True
+ if filepath != self.filepath:
+ self.filepath = filepath
+ change_ext = True
- return False
+ return (change_ext or change_axis)
class ImportHelper:
- filepath = StringProperty(name="File Path", description="Filepath used for importing the file", maxlen=1024, default="", subtype='FILE_PATH')
+ filepath = StringProperty(
+ name="File Path",
+ description="Filepath used for importing the file",
+ maxlen=1024,
+ subtype='FILE_PATH',
+ )
def invoke(self, context, event):
context.window_manager.fileselect_add(self)
return {'RUNNING_MODAL'}
+ def check(self, context):
+ return _check_axis_conversion(self)
+
# Axis conversion function, not pretty LUT
# use lookup tabes to convert between any axis
@@ -116,29 +147,75 @@ _axis_convert_matrix = (
# where all 4 values are or'd into a single value...
# (i1<<0 | i1<<3 | i1<<6 | i1<<9)
_axis_convert_lut = (
- {0x8C8, 0x4D0, 0x2E0, 0xAE8, 0x701, 0x511, 0x119, 0xB29, 0x682, 0x88A, 0x09A, 0x2A2, 0x80B, 0x413, 0x223, 0xA2B, 0x644, 0x454, 0x05C, 0xA6C, 0x745, 0x94D, 0x15D, 0x365},
- {0xAC8, 0x8D0, 0x4E0, 0x2E8, 0x741, 0x951, 0x159, 0x369, 0x702, 0xB0A, 0x11A, 0x522, 0xA0B, 0x813, 0x423, 0x22B, 0x684, 0x894, 0x09C, 0x2AC, 0x645, 0xA4D, 0x05D, 0x465},
- {0x4C8, 0x2D0, 0xAE0, 0x8E8, 0x681, 0x291, 0x099, 0x8A9, 0x642, 0x44A, 0x05A, 0xA62, 0x40B, 0x213, 0xA23, 0x82B, 0x744, 0x354, 0x15C, 0x96C, 0x705, 0x50D, 0x11D, 0xB25},
- {0x2C8, 0xAD0, 0x8E0, 0x4E8, 0x641, 0xA51, 0x059, 0x469, 0x742, 0x34A, 0x15A, 0x962, 0x20B, 0xA13, 0x823, 0x42B, 0x704, 0xB14, 0x11C, 0x52C, 0x685, 0x28D, 0x09D, 0x8A5},
- {0x708, 0xB10, 0x120, 0x528, 0x8C1, 0xAD1, 0x2D9, 0x4E9, 0x942, 0x74A, 0x35A, 0x162, 0x64B, 0xA53, 0x063, 0x46B, 0x804, 0xA14, 0x21C, 0x42C, 0x885, 0x68D, 0x29D, 0x0A5},
- {0xB08, 0x110, 0x520, 0x728, 0x941, 0x151, 0x359, 0x769, 0x802, 0xA0A, 0x21A, 0x422, 0xA4B, 0x053, 0x463, 0x66B, 0x884, 0x094, 0x29C, 0x6AC, 0x8C5, 0xACD, 0x2DD, 0x4E5},
- {0x508, 0x710, 0xB20, 0x128, 0x881, 0x691, 0x299, 0x0A9, 0x8C2, 0x4CA, 0x2DA, 0xAE2, 0x44B, 0x653, 0xA63, 0x06B, 0x944, 0x754, 0x35C, 0x16C, 0x805, 0x40D, 0x21D, 0xA25},
- {0x108, 0x510, 0x720, 0xB28, 0x801, 0x411, 0x219, 0xA29, 0x882, 0x08A, 0x29A, 0x6A2, 0x04B, 0x453, 0x663, 0xA6B, 0x8C4, 0x4D4, 0x2DC, 0xAEC, 0x945, 0x14D, 0x35D, 0x765},
- {0x748, 0x350, 0x160, 0x968, 0xAC1, 0x2D1, 0x4D9, 0x8E9, 0xA42, 0x64A, 0x45A, 0x062, 0x68B, 0x293, 0x0A3, 0x8AB, 0xA04, 0x214, 0x41C, 0x82C, 0xB05, 0x70D, 0x51D, 0x125},
- {0x948, 0x750, 0x360, 0x168, 0xB01, 0x711, 0x519, 0x129, 0xAC2, 0x8CA, 0x4DA, 0x2E2, 0x88B, 0x693, 0x2A3, 0x0AB, 0xA44, 0x654, 0x45C, 0x06C, 0xA05, 0x80D, 0x41D, 0x225},
- {0x348, 0x150, 0x960, 0x768, 0xA41, 0x051, 0x459, 0x669, 0xA02, 0x20A, 0x41A, 0x822, 0x28B, 0x093, 0x8A3, 0x6AB, 0xB04, 0x114, 0x51C, 0x72C, 0xAC5, 0x2CD, 0x4DD, 0x8E5},
- {0x148, 0x950, 0x760, 0x368, 0xA01, 0x811, 0x419, 0x229, 0xB02, 0x10A, 0x51A, 0x722, 0x08B, 0x893, 0x6A3, 0x2AB, 0xAC4, 0x8D4, 0x4DC, 0x2EC, 0xA45, 0x04D, 0x45D, 0x665},
- {0x688, 0x890, 0x0A0, 0x2A8, 0x4C1, 0x8D1, 0xAD9, 0x2E9, 0x502, 0x70A, 0xB1A, 0x122, 0x74B, 0x953, 0x163, 0x36B, 0x404, 0x814, 0xA1C, 0x22C, 0x445, 0x64D, 0xA5D, 0x065},
- {0x888, 0x090, 0x2A0, 0x6A8, 0x501, 0x111, 0xB19, 0x729, 0x402, 0x80A, 0xA1A, 0x222, 0x94B, 0x153, 0x363, 0x76B, 0x444, 0x054, 0xA5C, 0x66C, 0x4C5, 0x8CD, 0xADD, 0x2E5},
- {0x288, 0x690, 0x8A0, 0x0A8, 0x441, 0x651, 0xA59, 0x069, 0x4C2, 0x2CA, 0xADA, 0x8E2, 0x34B, 0x753, 0x963, 0x16B, 0x504, 0x714, 0xB1C, 0x12C, 0x405, 0x20D, 0xA1D, 0x825},
- {0x088, 0x290, 0x6A0, 0x8A8, 0x401, 0x211, 0xA19, 0x829, 0x442, 0x04A, 0xA5A, 0x662, 0x14B, 0x353, 0x763, 0x96B, 0x4C4, 0x2D4, 0xADC, 0x8EC, 0x505, 0x10D, 0xB1D, 0x725},
- {0x648, 0x450, 0x060, 0xA68, 0x2C1, 0x4D1, 0x8D9, 0xAE9, 0x282, 0x68A, 0x89A, 0x0A2, 0x70B, 0x513, 0x123, 0xB2B, 0x204, 0x414, 0x81C, 0xA2C, 0x345, 0x74D, 0x95D, 0x165},
- {0xA48, 0x650, 0x460, 0x068, 0x341, 0x751, 0x959, 0x169, 0x2C2, 0xACA, 0x8DA, 0x4E2, 0xB0B, 0x713, 0x523, 0x12B, 0x284, 0x694, 0x89C, 0x0AC, 0x205, 0xA0D, 0x81D, 0x425},
- {0x448, 0x050, 0xA60, 0x668, 0x281, 0x091, 0x899, 0x6A9, 0x202, 0x40A, 0x81A, 0xA22, 0x50B, 0x113, 0xB23, 0x72B, 0x344, 0x154, 0x95C, 0x76C, 0x2C5, 0x4CD, 0x8DD, 0xAE5},
- {0x048, 0xA50, 0x660, 0x468, 0x201, 0xA11, 0x819, 0x429, 0x342, 0x14A, 0x95A, 0x762, 0x10B, 0xB13, 0x723, 0x52B, 0x2C4, 0xAD4, 0x8DC, 0x4EC, 0x285, 0x08D, 0x89D, 0x6A5},
- {0x808, 0xA10, 0x220, 0x428, 0x101, 0xB11, 0x719, 0x529, 0x142, 0x94A, 0x75A, 0x362, 0x8CB, 0xAD3, 0x2E3, 0x4EB, 0x044, 0xA54, 0x65C, 0x46C, 0x085, 0x88D, 0x69D, 0x2A5},
- {0xA08, 0x210, 0x420, 0x828, 0x141, 0x351, 0x759, 0x969, 0x042, 0xA4A, 0x65A, 0x462, 0xACB, 0x2D3, 0x4E3, 0x8EB, 0x084, 0x294, 0x69C, 0x8AC, 0x105, 0xB0D, 0x71D, 0x525},
- {0x408, 0x810, 0xA20, 0x228, 0x081, 0x891, 0x699, 0x2A9, 0x102, 0x50A, 0x71A, 0xB22, 0x4CB, 0x8D3, 0xAE3, 0x2EB, 0x144, 0x954, 0x75C, 0x36C, 0x045, 0x44D, 0x65D, 0xA65},
+ {0x8C8, 0x4D0, 0x2E0, 0xAE8, 0x701, 0x511, 0x119, 0xB29, 0x682, 0x88A,
+ 0x09A, 0x2A2, 0x80B, 0x413, 0x223, 0xA2B, 0x644, 0x454, 0x05C, 0xA6C,
+ 0x745, 0x94D, 0x15D, 0x365},
+ {0xAC8, 0x8D0, 0x4E0, 0x2E8, 0x741, 0x951, 0x159, 0x369, 0x702, 0xB0A,
+ 0x11A, 0x522, 0xA0B, 0x813, 0x423, 0x22B, 0x684, 0x894, 0x09C, 0x2AC,
+ 0x645, 0xA4D, 0x05D, 0x465},
+ {0x4C8, 0x2D0, 0xAE0, 0x8E8, 0x681, 0x291, 0x099, 0x8A9, 0x642, 0x44A,
+ 0x05A, 0xA62, 0x40B, 0x213, 0xA23, 0x82B, 0x744, 0x354, 0x15C, 0x96C,
+ 0x705, 0x50D, 0x11D, 0xB25},
+ {0x2C8, 0xAD0, 0x8E0, 0x4E8, 0x641, 0xA51, 0x059, 0x469, 0x742, 0x34A,
+ 0x15A, 0x962, 0x20B, 0xA13, 0x823, 0x42B, 0x704, 0xB14, 0x11C, 0x52C,
+ 0x685, 0x28D, 0x09D, 0x8A5},
+ {0x708, 0xB10, 0x120, 0x528, 0x8C1, 0xAD1, 0x2D9, 0x4E9, 0x942, 0x74A,
+ 0x35A, 0x162, 0x64B, 0xA53, 0x063, 0x46B, 0x804, 0xA14, 0x21C, 0x42C,
+ 0x885, 0x68D, 0x29D, 0x0A5},
+ {0xB08, 0x110, 0x520, 0x728, 0x941, 0x151, 0x359, 0x769, 0x802, 0xA0A,
+ 0x21A, 0x422, 0xA4B, 0x053, 0x463, 0x66B, 0x884, 0x094, 0x29C, 0x6AC,
+ 0x8C5, 0xACD, 0x2DD, 0x4E5},
+ {0x508, 0x710, 0xB20, 0x128, 0x881, 0x691, 0x299, 0x0A9, 0x8C2, 0x4CA,
+ 0x2DA, 0xAE2, 0x44B, 0x653, 0xA63, 0x06B, 0x944, 0x754, 0x35C, 0x16C,
+ 0x805, 0x40D, 0x21D, 0xA25},
+ {0x108, 0x510, 0x720, 0xB28, 0x801, 0x411, 0x219, 0xA29, 0x882, 0x08A,
+ 0x29A, 0x6A2, 0x04B, 0x453, 0x663, 0xA6B, 0x8C4, 0x4D4, 0x2DC, 0xAEC,
+ 0x945, 0x14D, 0x35D, 0x765},
+ {0x748, 0x350, 0x160, 0x968, 0xAC1, 0x2D1, 0x4D9, 0x8E9, 0xA42, 0x64A,
+ 0x45A, 0x062, 0x68B, 0x293, 0x0A3, 0x8AB, 0xA04, 0x214, 0x41C, 0x82C,
+ 0xB05, 0x70D, 0x51D, 0x125},
+ {0x948, 0x750, 0x360, 0x168, 0xB01, 0x711, 0x519, 0x129, 0xAC2, 0x8CA,
+ 0x4DA, 0x2E2, 0x88B, 0x693, 0x2A3, 0x0AB, 0xA44, 0x654, 0x45C, 0x06C,
+ 0xA05, 0x80D, 0x41D, 0x225},
+ {0x348, 0x150, 0x960, 0x768, 0xA41, 0x051, 0x459, 0x669, 0xA02, 0x20A,
+ 0x41A, 0x822, 0x28B, 0x093, 0x8A3, 0x6AB, 0xB04, 0x114, 0x51C, 0x72C,
+ 0xAC5, 0x2CD, 0x4DD, 0x8E5},
+ {0x148, 0x950, 0x760, 0x368, 0xA01, 0x811, 0x419, 0x229, 0xB02, 0x10A,
+ 0x51A, 0x722, 0x08B, 0x893, 0x6A3, 0x2AB, 0xAC4, 0x8D4, 0x4DC, 0x2EC,
+ 0xA45, 0x04D, 0x45D, 0x665},
+ {0x688, 0x890, 0x0A0, 0x2A8, 0x4C1, 0x8D1, 0xAD9, 0x2E9, 0x502, 0x70A,
+ 0xB1A, 0x122, 0x74B, 0x953, 0x163, 0x36B, 0x404, 0x814, 0xA1C, 0x22C,
+ 0x445, 0x64D, 0xA5D, 0x065},
+ {0x888, 0x090, 0x2A0, 0x6A8, 0x501, 0x111, 0xB19, 0x729, 0x402, 0x80A,
+ 0xA1A, 0x222, 0x94B, 0x153, 0x363, 0x76B, 0x444, 0x054, 0xA5C, 0x66C,
+ 0x4C5, 0x8CD, 0xADD, 0x2E5},
+ {0x288, 0x690, 0x8A0, 0x0A8, 0x441, 0x651, 0xA59, 0x069, 0x4C2, 0x2CA,
+ 0xADA, 0x8E2, 0x34B, 0x753, 0x963, 0x16B, 0x504, 0x714, 0xB1C, 0x12C,
+ 0x405, 0x20D, 0xA1D, 0x825},
+ {0x088, 0x290, 0x6A0, 0x8A8, 0x401, 0x211, 0xA19, 0x829, 0x442, 0x04A,
+ 0xA5A, 0x662, 0x14B, 0x353, 0x763, 0x96B, 0x4C4, 0x2D4, 0xADC, 0x8EC,
+ 0x505, 0x10D, 0xB1D, 0x725},
+ {0x648, 0x450, 0x060, 0xA68, 0x2C1, 0x4D1, 0x8D9, 0xAE9, 0x282, 0x68A,
+ 0x89A, 0x0A2, 0x70B, 0x513, 0x123, 0xB2B, 0x204, 0x414, 0x81C, 0xA2C,
+ 0x345, 0x74D, 0x95D, 0x165},
+ {0xA48, 0x650, 0x460, 0x068, 0x341, 0x751, 0x959, 0x169, 0x2C2, 0xACA,
+ 0x8DA, 0x4E2, 0xB0B, 0x713, 0x523, 0x12B, 0x284, 0x694, 0x89C, 0x0AC,
+ 0x205, 0xA0D, 0x81D, 0x425},
+ {0x448, 0x050, 0xA60, 0x668, 0x281, 0x091, 0x899, 0x6A9, 0x202, 0x40A,
+ 0x81A, 0xA22, 0x50B, 0x113, 0xB23, 0x72B, 0x344, 0x154, 0x95C, 0x76C,
+ 0x2C5, 0x4CD, 0x8DD, 0xAE5},
+ {0x048, 0xA50, 0x660, 0x468, 0x201, 0xA11, 0x819, 0x429, 0x342, 0x14A,
+ 0x95A, 0x762, 0x10B, 0xB13, 0x723, 0x52B, 0x2C4, 0xAD4, 0x8DC, 0x4EC,
+ 0x285, 0x08D, 0x89D, 0x6A5},
+ {0x808, 0xA10, 0x220, 0x428, 0x101, 0xB11, 0x719, 0x529, 0x142, 0x94A,
+ 0x75A, 0x362, 0x8CB, 0xAD3, 0x2E3, 0x4EB, 0x044, 0xA54, 0x65C, 0x46C,
+ 0x085, 0x88D, 0x69D, 0x2A5},
+ {0xA08, 0x210, 0x420, 0x828, 0x141, 0x351, 0x759, 0x969, 0x042, 0xA4A,
+ 0x65A, 0x462, 0xACB, 0x2D3, 0x4E3, 0x8EB, 0x084, 0x294, 0x69C, 0x8AC,
+ 0x105, 0xB0D, 0x71D, 0x525},
+ {0x408, 0x810, 0xA20, 0x228, 0x081, 0x891, 0x699, 0x2A9, 0x102, 0x50A,
+ 0x71A, 0xB22, 0x4CB, 0x8D3, 0xAE3, 0x2EB, 0x144, 0x954, 0x75C, 0x36C,
+ 0x045, 0x44D, 0x65D, 0xA65},
)
_axis_convert_num = {'X': 0, 'Y': 1, 'Z': 2, '-X': 3, '-Y': 4, '-Z': 5}
@@ -159,14 +236,19 @@ def axis_conversion(from_forward='Y', from_up='Z', to_forward='Y', to_up='Z'):
raise Exception("invalid axis arguments passed, "
"can't use up/forward on the same axis.")
- value = reduce(int.__or__, (_axis_convert_num[a] << (i * 3) for i, a in enumerate((from_forward, from_up, to_forward, to_up))))
+ value = reduce(int.__or__, (_axis_convert_num[a] << (i * 3)
+ for i, a in enumerate((from_forward,
+ from_up,
+ to_forward,
+ to_up,
+ ))))
for i, axis_lut in enumerate(_axis_convert_lut):
if value in axis_lut:
return Matrix(_axis_convert_matrix[i])
assert(0)
-
+
def axis_conversion_ensure(operator, forward_attr, up_attr):
"""
Function to ensure an operator has valid axis conversion settings, intended
@@ -174,9 +256,9 @@ def axis_conversion_ensure(operator, forward_attr, up_attr):
:arg operator: the operator to access axis attributes from.
:type operator: :class:`Operator`
- :arg forward_attr:
+ :arg forward_attr: attribute storing the forward axis
:type forward_attr: string
- :arg up_attr: the directory the *filepath* will be referenced from (normally the export path).
+ :arg up_attr: attribute storing the up axis
:type up_attr: string
:return: True if the value was modified.
:rtype: boolean
@@ -184,9 +266,9 @@ def axis_conversion_ensure(operator, forward_attr, up_attr):
def validate(axis_forward, axis_up):
if axis_forward[-1] == axis_up[-1]:
axis_up = axis_up[0:-1] + 'XYZ'[('XYZ'.index(axis_up[-1]) + 1) % 3]
-
+
return axis_forward, axis_up
-
+
change = False
axis = getattr(operator, forward_attr), getattr(operator, up_attr)
@@ -201,9 +283,10 @@ def axis_conversion_ensure(operator, forward_attr, up_attr):
return False
-# return a tuple (free, object list), free is True if memory should be freed later with free_derived_objects()
+# return a tuple (free, object list), free is True if memory should be freed
+# later with free_derived_objects()
def create_derived_objects(scene, ob):
- if ob.parent and ob.parent.dupli_type != 'NONE':
+ if ob.parent and ob.parent.dupli_type in {'VERTS', 'FACES'}:
return False, None
if ob.dupli_type != 'NONE':
@@ -249,31 +332,45 @@ path_reference_mode = EnumProperty(
description="Method used to reference paths",
items=(('AUTO', "Auto", "Use Relative paths with subdirectories only"),
('ABSOLUTE', "Absolute", "Always write absolute paths"),
- ('RELATIVE', "Relative", "Always write relative patsh (where possible)"),
- ('MATCH', "Match", "Match Absolute/Relative setting with input path"),
+ ('RELATIVE', "Relative", "Always write relative patsh "
+ "(where possible)"),
+ ('MATCH', "Match", "Match Absolute/Relative "
+ "setting with input path"),
('STRIP', "Strip Path", "Filename only"),
- ('COPY', "Copy", "copy the file to the destination path (or subdirectory)"),
+ ('COPY', "Copy", "copy the file to the destination path "
+ "(or subdirectory)"),
),
default='AUTO'
)
-def path_reference(filepath, base_src, base_dst, mode='AUTO', copy_subdir="", copy_set=None):
+def path_reference(filepath,
+ base_src,
+ base_dst,
+ mode='AUTO',
+ copy_subdir="",
+ copy_set=None,
+ ):
"""
Return a filepath relative to a destination directory, for use with
exporters.
- :arg filepath: the file path to return, supporting blenders relative '//' prefix.
+ :arg filepath: the file path to return,
+ supporting blenders relative '//' prefix.
:type filepath: string
- :arg base_src: the directory the *filepath* is relative too (normally the blend file).
+ :arg base_src: the directory the *filepath* is relative too
+ (normally the blend file).
:type base_src: string
- :arg base_dst: the directory the *filepath* will be referenced from (normally the export path).
+ :arg base_dst: the directory the *filepath* will be referenced from
+ (normally the export path).
:type base_dst: string
- :arg mode: the method used get the path in ['AUTO', 'ABSOLUTE', 'RELATIVE', 'MATCH', 'STRIP', 'COPY']
+ :arg mode: the method used get the path in
+ ['AUTO', 'ABSOLUTE', 'RELATIVE', 'MATCH', 'STRIP', 'COPY']
:type mode: string
:arg copy_subdir: the subdirectory of *base_dst* to use when mode='COPY'.
:type copy_subdir: string
- :arg copy_set: collect from/to pairs when mode='COPY', pass to *path_reference_copy* when exportign is done.
+ :arg copy_set: collect from/to pairs when mode='COPY',
+ pass to *path_reference_copy* when exportign is done.
:type copy_set: set
:return: the new filepath.
:rtype: string
@@ -287,7 +384,9 @@ def path_reference(filepath, base_src, base_dst, mode='AUTO', copy_subdir="", co
elif mode == 'MATCH':
mode = 'RELATIVE' if is_relative else 'ABSOLUTE'
elif mode == 'AUTO':
- mode = 'RELATIVE' if bpy.path.is_subdir(filepath, base_dst) else 'ABSOLUTE'
+ mode = ('RELATIVE'
+ if bpy.path.is_subdir(filepath, base_dst)
+ else 'ABSOLUTE')
elif mode == 'COPY':
if copy_subdir:
subdir_abs = os.path.join(os.path.normpath(base_dst), copy_subdir)
@@ -362,7 +461,8 @@ def unique_name(key, name, name_dict, name_max=-1, clean_func=None):
if name_new is None:
count = 1
name_dict_values = name_dict.values()
- name_new = name_new_orig = name if clean_func is None else clean_func(name)
+ name_new = name_new_orig = (name if clean_func is None
+ else clean_func(name))
if name_max == -1:
while name_new in name_dict_values:
@@ -372,7 +472,10 @@ def unique_name(key, name, name_dict, name_max=-1, clean_func=None):
name_new = name_new[:name_max]
while name_new in name_dict_values:
count_str = "%03d" % count
- name_new = "%.*s.%s" % (name_max - (len(count_str) + 1), name_new_orig, count_str)
+ name_new = "%.*s.%s" % (name_max - (len(count_str) + 1),
+ name_new_orig,
+ count_str,
+ )
count += 1
name_dict[key] = name_new
diff --git a/release/scripts/modules/bpy_extras/mesh_utils.py b/release/scripts/modules/bpy_extras/mesh_utils.py
index c42d3d0236a..f9400674138 100644
--- a/release/scripts/modules/bpy_extras/mesh_utils.py
+++ b/release/scripts/modules/bpy_extras/mesh_utils.py
@@ -26,7 +26,7 @@ __all__ = (
"edge_loops_from_edges",
"ngon_tesselate",
"face_random_points",
-)
+ )
def mesh_linked_faces(mesh):
@@ -170,8 +170,8 @@ def edge_loops_from_faces(mesh, faces=None, seams=()):
# from knowing the last 2, look for th next.
ed_adj = edges[context_loop[-1]]
if len(ed_adj) != 2:
-
- if other_dir and flipped == False: # the original edge had 2 other edges
+ # the original edge had 2 other edges
+ if other_dir and flipped == False:
flipped = True # only flip the list once
context_loop.reverse()
ed_adj[:] = []
@@ -259,13 +259,15 @@ def edge_loops_from_edges(mesh, edges=None):
def ngon_tesselate(from_data, indices, fix_loops=True):
'''
- Takes a polyline of indices (fgon)
- and returns a list of face indicie lists.
- Designed to be used for importers that need indices for an fgon to create from existing verts.
+ Takes a polyline of indices (fgon) and returns a list of face
+ indicie lists. Designed to be used for importers that need indices for an
+ fgon to create from existing verts.
from_data: either a mesh, or a list/tuple of vectors.
- indices: a list of indices to use this list is the ordered closed polyline to fill, and can be a subset of the data given.
- fix_loops: If this is enabled polylines that use loops to make multiple polylines are delt with correctly.
+ indices: a list of indices to use this list is the ordered closed polyline
+ to fill, and can be a subset of the data given.
+ fix_loops: If this is enabled polylines that use loops to make multiple
+ polylines are delt with correctly.
'''
from mathutils.geometry import tesselate_polygon
@@ -276,7 +278,8 @@ def ngon_tesselate(from_data, indices, fix_loops=True):
return []
def mlen(co):
- return abs(co[0]) + abs(co[1]) + abs(co[2]) # manhatten length of a vector, faster then length
+ # manhatten length of a vector, faster then length
+ return abs(co[0]) + abs(co[1]) + abs(co[2])
def vert_treplet(v, i):
return v, vector_to_tuple(v, 6), i, mlen(v)
@@ -296,7 +299,8 @@ def ngon_tesselate(from_data, indices, fix_loops=True):
else:
verts = [from_data.vertices[i].co for ii, i in enumerate(indices)]
- for i in range(len(verts) - 1, 0, -1): # same as reversed(xrange(1, len(verts))):
+ # same as reversed(range(1, len(verts))):
+ for i in range(len(verts) - 1, 0, -1):
if verts[i][1] == verts[i - 1][0]:
verts.pop(i - 1)
@@ -304,14 +308,16 @@ def ngon_tesselate(from_data, indices, fix_loops=True):
else:
'''
- Seperate this loop into multiple loops be finding edges that are used twice
- This is used by lightwave LWO files a lot
+ Seperate this loop into multiple loops be finding edges that are
+ used twice. This is used by lightwave LWO files a lot
'''
if type(from_data) in (tuple, list):
- verts = [vert_treplet(Vector(from_data[i]), ii) for ii, i in enumerate(indices)]
+ verts = [vert_treplet(Vector(from_data[i]), ii)
+ for ii, i in enumerate(indices)]
else:
- verts = [vert_treplet(from_data.vertices[i].co, ii) for ii, i in enumerate(indices)]
+ verts = [vert_treplet(from_data.vertices[i].co, ii)
+ for ii, i in enumerate(indices)]
edges = [(i, i - 1) for i in range(len(verts))]
if edges:
diff --git a/release/scripts/modules/bpy_extras/object_utils.py b/release/scripts/modules/bpy_extras/object_utils.py
index 51a8d4b5e23..790f5ba48cb 100644
--- a/release/scripts/modules/bpy_extras/object_utils.py
+++ b/release/scripts/modules/bpy_extras/object_utils.py
@@ -16,12 +16,12 @@
#
# ##### END GPL LICENSE BLOCK #####
-# <pep8 compliant>
+# <pep8-80 compliant>
__all__ = (
"add_object_align_init",
"object_data_add",
-)
+ )
import bpy
@@ -39,42 +39,49 @@ def add_object_align_init(context, operator):
:return: the matrix from the context and settings.
:rtype: :class:`Matrix`
"""
+
+ from mathutils import Matrix, Vector, Euler
+ properties = operator.properties if operator is not None else None
+
space_data = context.space_data
if space_data.type != 'VIEW_3D':
space_data = None
# location
- if operator and operator.properties.is_property_set("location"):
- location = mathutils.Matrix.Translation(mathutils.Vector(operator.properties.location))
+ if operator and properties.is_property_set("location"):
+ location = Matrix.Translation(Vector(properties.location))
else:
if space_data: # local view cursor is detected below
- location = mathutils.Matrix.Translation(space_data.cursor_location)
+ location = Matrix.Translation(space_data.cursor_location)
else:
- location = mathutils.Matrix.Translation(context.scene.cursor_location)
+ location = Matrix.Translation(context.scene.cursor_location)
if operator:
- operator.properties.location = location.to_translation()
+ properties.location = location.to_translation()
# rotation
view_align = (context.user_preferences.edit.object_align == 'VIEW')
view_align_force = False
if operator:
- if operator.properties.is_property_set("view_align"):
+ if properties.is_property_set("view_align"):
view_align = view_align_force = operator.view_align
else:
- operator.properties.view_align = view_align
+ properties.view_align = view_align
- if operator and operator.properties.is_property_set("rotation") and not view_align_force:
- rotation = mathutils.Euler(operator.properties.rotation).to_matrix().to_4x4()
+ if operator and (properties.is_property_set("rotation") and
+ not view_align_force):
+
+ rotation = Euler(properties.rotation).to_matrix().to_4x4()
else:
if view_align and space_data:
- rotation = space_data.region_3d.view_matrix.to_3x3().inverted().to_4x4()
+ rotation = space_data.region_3d.view_matrix.to_3x3().inverted()
+ rotation.resize_4x4()
else:
rotation = mathutils.Matrix()
# set the operator properties
if operator:
- operator.properties.rotation = rotation.to_euler()
+ properties.rotation = rotation.to_euler()
return location * rotation
@@ -114,14 +121,18 @@ def object_data_add(context, obdata, operator=None):
# XXX
# caused because entering editmodedoes not add a empty undo slot!
if context.user_preferences.edit.use_enter_edit_mode:
- if not (obj_act and obj_act.mode == 'EDIT' and obj_act.type == obj_new.type):
+ if not (obj_act and
+ obj_act.mode == 'EDIT' and
+ obj_act.type == obj_new.type):
+
_obdata = bpy.data.meshes.new(obdata.name)
obj_act = bpy.data.objects.new(_obdata.name, _obdata)
obj_act.matrix_world = obj_new.matrix_world
scene.objects.link(obj_act)
scene.objects.active = obj_act
bpy.ops.object.mode_set(mode='EDIT')
- bpy.ops.ed.undo_push(message="Enter Editmode") # need empty undo step
+ # need empty undo step
+ bpy.ops.ed.undo_push(message="Enter Editmode")
# XXX
if obj_act and obj_act.mode == 'EDIT' and obj_act.type == obj_new.type:
diff --git a/release/scripts/modules/bpy_extras/view3d_utils.py b/release/scripts/modules/bpy_extras/view3d_utils.py
index c0c0f9186bd..26325633a05 100644
--- a/release/scripts/modules/bpy_extras/view3d_utils.py
+++ b/release/scripts/modules/bpy_extras/view3d_utils.py
@@ -16,13 +16,13 @@
#
# ##### END GPL LICENSE BLOCK #####
-# <pep8 compliant>
+# <pep8-80 compliant>
__all__ = (
"region_2d_to_vector_3d",
"region_2d_to_location_3d",
"location_3d_to_region_2d",
-)
+ )
def region_2d_to_vector_3d(region, rv3d, coord):
@@ -50,11 +50,11 @@ def region_2d_to_vector_3d(region, rv3d, coord):
-0.5
))
- w = (out[0] * persinv[0][3]) + \
- (out[1] * persinv[1][3]) + \
- (out[2] * persinv[2][3]) + persinv[3][3]
+ w = ((out[0] * persinv[0][3]) +
+ (out[1] * persinv[1][3]) +
+ (out[2] * persinv[2][3]) + persinv[3][3])
- return ((out * persinv) / w) - rv3d.view_matrix.inverted()[3].xyz
+ return ((persinv * out) / w) - rv3d.view_matrix.inverted()[3].xyz
else:
return rv3d.view_matrix.inverted()[2].xyz.normalized()
@@ -90,15 +90,23 @@ def region_2d_to_location_3d(region, rv3d, coord, depth_location):
origin_start = rv3d.view_matrix.inverted()[3].to_3d()
origin_end = origin_start + coord_vec
view_vec = rv3d.view_matrix.inverted()[2]
- return intersect_line_plane(origin_start, origin_end, depth_location, view_vec, 1)
+ return intersect_line_plane(origin_start,
+ origin_end,
+ depth_location,
+ view_vec, 1,
+ )
else:
dx = (2.0 * coord[0] / region.width) - 1.0
dy = (2.0 * coord[1] / region.height) - 1.0
persinv = persmat.inverted()
viewinv = rv3d.view_matrix.inverted()
- origin_start = (persinv[0].xyz * dx) + (persinv[1].xyz * dy) + viewinv[3].xyz
+ origin_start = ((persinv[0].xyz * dx) +
+ (persinv[1].xyz * dy) + viewinv[3].xyz)
origin_end = origin_start + coord_vec
- return intersect_point_line(depth_location, origin_start, origin_end)[0]
+ return intersect_point_line(depth_location,
+ origin_start,
+ origin_end,
+ )[0]
def location_3d_to_region_2d(region, rv3d, coord):
@@ -116,7 +124,7 @@ def location_3d_to_region_2d(region, rv3d, coord):
"""
from mathutils import Vector
- prj = Vector((coord[0], coord[1], coord[2], 1.0)) * rv3d.perspective_matrix
+ prj = rv3d.perspective_matrix * Vector((coord[0], coord[1], coord[2], 1.0))
if prj.w > 0.0:
width_half = region.width / 2.0
height_half = region.height / 2.0
diff --git a/release/scripts/modules/bpy_types.py b/release/scripts/modules/bpy_types.py
index f2cd46b20ae..8766c873dd8 100644
--- a/release/scripts/modules/bpy_types.py
+++ b/release/scripts/modules/bpy_types.py
@@ -144,21 +144,21 @@ class _GenericBone:
""" Vector pointing down the x-axis of the bone.
"""
from mathutils import Vector
- return Vector((1.0, 0.0, 0.0)) * self.matrix.to_3x3()
+ return self.matrix.to_3x3() * Vector((1.0, 0.0, 0.0))
@property
def y_axis(self):
""" Vector pointing down the x-axis of the bone.
"""
from mathutils import Vector
- return Vector((0.0, 1.0, 0.0)) * self.matrix.to_3x3()
+ return self.matrix.to_3x3() * Vector((0.0, 1.0, 0.0))
@property
def z_axis(self):
""" Vector pointing down the x-axis of the bone.
"""
from mathutils import Vector
- return Vector((0.0, 0.0, 1.0)) * self.matrix.to_3x3()
+ return self.matrix.to_3x3() * Vector((0.0, 0.0, 1.0))
@property
def basename(self):
@@ -294,9 +294,9 @@ class EditBone(StructRNA, _GenericBone, metaclass=StructMetaPropGroup):
:type roll: bool
"""
from mathutils import Vector
- z_vec = Vector((0.0, 0.0, 1.0)) * self.matrix.to_3x3()
- self.tail = self.tail * matrix
- self.head = self.head * matrix
+ z_vec = self.matrix.to_3x3() * Vector((0.0, 0.0, 1.0))
+ self.tail = matrix * self.tail
+ self.head = matrix * self.head
if scale:
scalar = matrix.median_scale
@@ -304,7 +304,7 @@ class EditBone(StructRNA, _GenericBone, metaclass=StructMetaPropGroup):
self.tail_radius *= scalar
if roll:
- self.align_roll(z_vec * matrix)
+ self.align_roll(matrix * z_vec)
def ord_ind(i1, i2):
diff --git a/release/scripts/modules/keyingsets_utils.py b/release/scripts/modules/keyingsets_utils.py
index dc61ce2a4af..03400edc904 100644
--- a/release/scripts/modules/keyingsets_utils.py
+++ b/release/scripts/modules/keyingsets_utils.py
@@ -16,14 +16,14 @@
#
# ##### END GPL LICENSE BLOCK #####
-# <pep8 compliant>
+# <pep8-80 compliant>
# This file defines a set of methods that are useful for various
# Relative Keying Set (RKS) related operations, such as: callbacks
# for polling, iterator callbacks, and also generate callbacks.
# All of these can be used in conjunction with the others.
-__all__ = [
+__all__ = (
"path_add_property",
"RKS_POLL_selected_objects",
"RKS_POLL_selected_bones",
@@ -33,7 +33,7 @@ __all__ = [
"RKS_GEN_location",
"RKS_GEN_rotation",
"RKS_GEN_scaling",
-]
+ )
import bpy
@@ -75,7 +75,8 @@ def RKS_POLL_selected_bones(ksi, context):
# selected bones or objects
def RKS_POLL_selected_items(ksi, context):
- return RKS_POLL_selected_bones(ksi, context) or RKS_POLL_selected_objects(ksi, context)
+ return (RKS_POLL_selected_bones(ksi, context) or
+ RKS_POLL_selected_objects(ksi, context))
###########################
# Iterator Callbacks
diff --git a/release/scripts/presets/ffmpeg/xvid.py b/release/scripts/presets/ffmpeg/xvid.py
index fa64562e566..c006ba267cc 100644
--- a/release/scripts/presets/ffmpeg/xvid.py
+++ b/release/scripts/presets/ffmpeg/xvid.py
@@ -1,8 +1,7 @@
import bpy
is_ntsc = (bpy.context.scene.render.fps != 25)
-bpy.context.scene.render.ffmpeg_format = "AVI"
-bpy.context.scene.render.ffmpeg_codec = "XVID"
+bpy.context.scene.render.ffmpeg_format = "XVID"
if is_ntsc:
bpy.context.scene.render.ffmpeg_gopsize = 18
diff --git a/release/scripts/startup/bl_operators/add_mesh_torus.py b/release/scripts/startup/bl_operators/add_mesh_torus.py
index 6ab803cc469..27a6d21d519 100644
--- a/release/scripts/startup/bl_operators/add_mesh_torus.py
+++ b/release/scripts/startup/bl_operators/add_mesh_torus.py
@@ -16,7 +16,7 @@
#
# ##### END GPL LICENSE BLOCK #####
-# <pep8 compliant>
+# <pep8-80 compliant>
import bpy
import mathutils
@@ -40,8 +40,10 @@ def add_torus(major_rad, minor_rad, major_seg, minor_seg):
for minor_index in range(minor_seg):
angle = 2 * pi * minor_index / minor_seg
- vec = Vector((major_rad + (cos(angle) * minor_rad), 0.0,
- (sin(angle) * minor_rad))) * quat
+ vec = quat * Vector((major_rad + (cos(angle) * minor_rad),
+ 0.0,
+ (sin(angle) * minor_rad),
+ ))
verts.extend(vec[:])
@@ -72,7 +74,11 @@ def add_torus(major_rad, minor_rad, major_seg, minor_seg):
return verts, faces
-from bpy.props import FloatProperty, IntProperty, BoolProperty, FloatVectorProperty
+from bpy.props import (FloatProperty,
+ IntProperty,
+ BoolProperty,
+ FloatVectorProperty,
+ )
class AddTorus(bpy.types.Operator):
@@ -82,7 +88,8 @@ class AddTorus(bpy.types.Operator):
bl_options = {'REGISTER', 'UNDO'}
major_radius = FloatProperty(name="Major Radius",
- description="Radius from the origin to the center of the cross sections",
+ description=("Radius from the origin to the "
+ "center of the cross sections"),
default=1.0, min=0.01, max=100.0)
minor_radius = FloatProperty(name="Minor Radius",
description="Radius of the torus' cross section",
diff --git a/release/scripts/startup/bl_operators/image.py b/release/scripts/startup/bl_operators/image.py
index 4bb53f776ba..23bafe2eaae 100644
--- a/release/scripts/startup/bl_operators/image.py
+++ b/release/scripts/startup/bl_operators/image.py
@@ -16,7 +16,7 @@
#
# ##### END GPL LICENSE BLOCK #####
-# <pep8 compliant>
+# <pep8-80 compliant>
import bpy
from bpy.props import StringProperty
@@ -28,7 +28,11 @@ class EditExternally(bpy.types.Operator):
bl_label = "Image Edit Externally"
bl_options = {'REGISTER'}
- filepath = StringProperty(name="File Path", description="Path to an image file", maxlen=1024, default="")
+ filepath = StringProperty(
+ name="File Path",
+ description="Path to an image file",
+ maxlen=1024,
+ )
def _editor_guess(self, context):
import sys
@@ -57,10 +61,13 @@ class EditExternally(bpy.types.Operator):
def execute(self, context):
import os
import subprocess
- filepath = bpy.path.abspath(self.filepath)
+ filepath = os.path.normpath(bpy.path.abspath(self.filepath))
if not os.path.exists(filepath):
- self.report({'ERROR'}, "Image path %r not found, image may be packed or unsaved." % filepath)
+ self.report({'ERROR'},
+ "Image path %r not found, image may be packed or "
+ "unsaved." % filepath)
+
return {'CANCELLED'}
cmd = self._editor_guess(context) + [filepath]
@@ -70,7 +77,10 @@ class EditExternally(bpy.types.Operator):
except:
import traceback
traceback.print_exc()
- self.report({'ERROR'}, "Image editor not found, please specify in User Preferences > File")
+ self.report({'ERROR'},
+ "Image editor not found, "
+ "please specify in User Preferences > File")
+
return {'CANCELLED'}
return {'FINISHED'}
@@ -104,7 +114,9 @@ class SaveDirty(bpy.types.Operator):
if "\\" not in filepath and "/" not in filepath:
self.report({'WARNING'}, "Invalid path: " + filepath)
elif filepath in unique_paths:
- self.report({'WARNING'}, "Path used by more then one image: " + filepath)
+ self.report({'WARNING'},
+ "Path used by more then one image: %r" %
+ filepath)
else:
unique_paths.add(filepath)
image.save()
@@ -142,14 +154,14 @@ class ProjectEdit(bpy.types.Operator):
filepath = os.path.basename(bpy.data.filepath)
filepath = os.path.splitext(filepath)[0]
- # filepath = bpy.path.clean_name(filepath) # fixes <memory> rubbish, needs checking
+ # fixes <memory> rubbish, needs checking
+ # filepath = bpy.path.clean_name(filepath)
- if filepath.startswith(".") or filepath == "":
- # TODO, have a way to check if the file is saved, assume startup.blend
+ if bpy.data.is_saved:
+ filepath = "//" + filepath
+ else:
tmpdir = context.user_preferences.filepaths.temporary_directory
filepath = os.path.join(tmpdir, "project_edit")
- else:
- filepath = "//" + filepath
obj = context.object
diff --git a/release/scripts/startup/bl_operators/mesh.py b/release/scripts/startup/bl_operators/mesh.py
index 03b0e469310..344b238709f 100644
--- a/release/scripts/startup/bl_operators/mesh.py
+++ b/release/scripts/startup/bl_operators/mesh.py
@@ -16,7 +16,7 @@
#
# ##### END GPL LICENSE BLOCK #####
-# <pep8 compliant>
+# <pep8-80 compliant>
import bpy
@@ -111,7 +111,8 @@ class MeshMirrorUV(bpy.types.Operator):
#for i, v in enumerate(mesh.vertices):
vmap = {}
- for mirror_a, mirror_b in (mirror_gt, mirror_lt), (mirror_lt, mirror_gt):
+ for mirror_a, mirror_b in ((mirror_gt, mirror_lt),
+ (mirror_lt, mirror_gt)):
for co, i in mirror_a.items():
nco = (-co[0], co[1], co[2])
j = mirror_b.get(nco)
@@ -120,7 +121,8 @@ class MeshMirrorUV(bpy.types.Operator):
active_uv_layer = mesh.uv_textures.active.data
fuvs = [(uv.uv1, uv.uv2, uv.uv3, uv.uv4) for uv in active_uv_layer]
- fuvs_cpy = [(uv[0].copy(), uv[1].copy(), uv[2].copy(), uv[3].copy()) for uv in fuvs]
+ fuvs_cpy = [(uv[0].copy(), uv[1].copy(), uv[2].copy(), uv[3].copy())
+ for uv in fuvs]
# as a list
faces = mesh.faces[:]
diff --git a/release/scripts/startup/bl_operators/object.py b/release/scripts/startup/bl_operators/object.py
index 0342a14a1b2..627a1530fe1 100644
--- a/release/scripts/startup/bl_operators/object.py
+++ b/release/scripts/startup/bl_operators/object.py
@@ -16,7 +16,7 @@
#
# ##### END GPL LICENSE BLOCK #####
-# <pep8 compliant>
+# <pep8-80 compliant>
import bpy
from bpy.props import StringProperty, BoolProperty, EnumProperty, IntProperty
@@ -28,9 +28,22 @@ class SelectPattern(bpy.types.Operator):
bl_label = "Select Pattern"
bl_options = {'REGISTER', 'UNDO'}
- pattern = StringProperty(name="Pattern", description="Name filter using '*' and '?' wildcard chars", maxlen=32, default="*")
- case_sensitive = BoolProperty(name="Case Sensitive", description="Do a case sensitive compare", default=False)
- extend = BoolProperty(name="Extend", description="Extend the existing selection", default=True)
+ pattern = StringProperty(
+ name="Pattern",
+ description="Name filter using '*' and '?' wildcard chars",
+ maxlen=32,
+ default="*",
+ )
+ case_sensitive = BoolProperty(
+ name="Case Sensitive",
+ description="Do a case sensitive compare",
+ default=False,
+ )
+ extend = BoolProperty(
+ name="Extend",
+ description="Extend the existing selection",
+ default=True,
+ )
def execute(self, context):
@@ -39,22 +52,37 @@ class SelectPattern(bpy.types.Operator):
if self.case_sensitive:
pattern_match = fnmatch.fnmatchcase
else:
- pattern_match = lambda a, b: fnmatch.fnmatchcase(a.upper(), b.upper())
-
+ pattern_match = (lambda a, b:
+ fnmatch.fnmatchcase(a.upper(), b.upper()))
+ is_ebone = False
obj = context.object
if obj and obj.mode == 'POSE':
items = obj.data.bones
+ if not self.extend:
+ bpy.ops.pose.select_all(action='DESELECT')
elif obj and obj.type == 'ARMATURE' and obj.mode == 'EDIT':
items = obj.data.edit_bones
+ if not self.extend:
+ bpy.ops.armature.select_all(action='DESELECT')
+ is_ebone = True
else:
items = context.visible_objects
+ if not self.extend:
+ bpy.ops.object.select_all(action='DESELECT')
# Can be pose bones or objects
for item in items:
if pattern_match(item.name, self.pattern):
item.select = True
- elif not self.extend:
- item.select = False
+
+ # hrmf, perhaps there should be a utility function for this.
+ if is_ebone:
+ item.select_head = True
+ item.select_tail = True
+ if item.use_connect:
+ item_parent = item.parent
+ if item_parent is not None:
+ item_parent.select_tail = True
return {'FINISHED'}
@@ -93,19 +121,25 @@ class SelectCamera(bpy.types.Operator):
class SelectHierarchy(bpy.types.Operator):
- '''Select object relative to the active objects position in the hierarchy'''
+ '''Select object relative to the active objects position''' \
+ '''in the hierarchy'''
bl_idname = "object.select_hierarchy"
bl_label = "Select Hierarchy"
bl_options = {'REGISTER', 'UNDO'}
- direction = EnumProperty(items=(
- ('PARENT', "Parent", ""),
- ('CHILD', "Child", "")),
- name="Direction",
- description="Direction to select in the hierarchy",
- default='PARENT')
+ direction = EnumProperty(
+ items=(('PARENT', "Parent", ""),
+ ('CHILD', "Child", ""),
+ ),
+ name="Direction",
+ description="Direction to select in the hierarchy",
+ default='PARENT')
- extend = BoolProperty(name="Extend", description="Extend the existing selection", default=False)
+ extend = BoolProperty(
+ name="Extend",
+ description="Extend the existing selection",
+ default=False,
+ )
@classmethod
def poll(cls, context):
@@ -163,7 +197,12 @@ class SubdivisionSet(bpy.types.Operator):
level = IntProperty(name="Level",
default=1, min=-100, max=100, soft_min=-6, soft_max=6)
- relative = BoolProperty(name="Relative", description="Apply the subsurf level as an offset relative to the current level", default=False)
+ relative = BoolProperty(
+ name="Relative",
+ description=("Apply the subsurf level as an offset "
+ "relative to the current level"),
+ default=False,
+ )
@classmethod
def poll(cls, context):
@@ -215,7 +254,8 @@ class SubdivisionSet(bpy.types.Operator):
mod = obj.modifiers.new("Subsurf", 'SUBSURF')
mod.levels = level
except:
- self.report({'WARNING'}, "Modifiers cannot be added to object: " + obj.name)
+ self.report({'WARNING'},
+ "Modifiers cannot be added to object: " + obj.name)
for obj in context.selected_editable_objects:
set_object_subd(obj)
@@ -224,23 +264,37 @@ class SubdivisionSet(bpy.types.Operator):
class ShapeTransfer(bpy.types.Operator):
- '''Copy another selected objects active shape to this one by applying the relative offsets'''
+ '''Copy another selected objects active shape to this one by ''' \
+ '''applying the relative offsets'''
bl_idname = "object.shape_key_transfer"
bl_label = "Transfer Shape Key"
bl_options = {'REGISTER', 'UNDO'}
- mode = EnumProperty(items=(
- ('OFFSET', "Offset", "Apply the relative positional offset"),
- ('RELATIVE_FACE', "Relative Face", "Calculate the geometricly relative position (using faces)."),
- ('RELATIVE_EDGE', "Relative Edge", "Calculate the geometricly relative position (using edges).")),
- name="Transformation Mode",
- description="Method to apply relative shape positions to the new shape",
- default='OFFSET')
-
- use_clamp = BoolProperty(name="Clamp Offset",
- description="Clamp the transformation to the distance each vertex moves in the original shape.",
- default=False)
+ mode = EnumProperty(
+ items=(('OFFSET',
+ "Offset",
+ "Apply the relative positional offset",
+ ),
+ ('RELATIVE_FACE',
+ "Relative Face",
+ "Calculate relative position (using faces).",
+ ),
+ ('RELATIVE_EDGE',
+ "Relative Edge",
+ "Calculate relative position (using edges).",
+ ),
+ ),
+ name="Transformation Mode",
+ description="Relative shape positions to the new shape method",
+ default='OFFSET',
+ )
+ use_clamp = BoolProperty(
+ name="Clamp Offset",
+ description=("Clamp the transformation to the distance each "
+ "vertex moves in the original shape."),
+ default=False,
+ )
def _main(self, ob_act, objects, mode='OFFSET', use_clamp=False):
@@ -272,13 +326,16 @@ class ShapeTransfer(bpy.types.Operator):
orig_shape_coords = me_cos(ob_act.active_shape_key.data)
orig_normals = me_nos(me.vertices)
- # orig_coords = me_cos(me.vertices) # the actual mverts location isnt as relyable as the base shape :S
+ # the actual mverts location isnt as relyable as the base shape :S
+ # orig_coords = me_cos(me.vertices)
orig_coords = me_cos(me.shape_keys.key_blocks[0].data)
for ob_other in objects:
me_other = ob_other.data
if len(me_other.vertices) != len(me.vertices):
- self.report({'WARNING'}, "Skipping '%s', vertex count differs" % ob_other.name)
+ self.report({'WARNING'},
+ ("Skipping '%s', "
+ "vertex count differs") % ob_other.name)
continue
target_normals = me_nos(me_other.vertices)
@@ -290,53 +347,90 @@ class ShapeTransfer(bpy.types.Operator):
ob_add_shape(ob_other, orig_key_name)
# editing the final coords, only list that stores wrapped coords
- target_shape_coords = [v.co for v in ob_other.active_shape_key.data]
+ target_shape_coords = [v.co for v in
+ ob_other.active_shape_key.data]
median_coords = [[] for i in range(len(me.vertices))]
# Method 1, edge
if mode == 'OFFSET':
for i, vert_cos in enumerate(median_coords):
- vert_cos.append(target_coords[i] + (orig_shape_coords[i] - orig_coords[i]))
+ vert_cos.append(target_coords[i] +
+ (orig_shape_coords[i] - orig_coords[i]))
elif mode == 'RELATIVE_FACE':
for face in me.faces:
i1, i2, i3, i4 = face.vertices_raw
if i4 != 0:
pt = barycentric_transform(orig_shape_coords[i1],
- orig_coords[i4], orig_coords[i1], orig_coords[i2],
- target_coords[i4], target_coords[i1], target_coords[i2])
+ orig_coords[i4],
+ orig_coords[i1],
+ orig_coords[i2],
+ target_coords[i4],
+ target_coords[i1],
+ target_coords[i2],
+ )
median_coords[i1].append(pt)
pt = barycentric_transform(orig_shape_coords[i2],
- orig_coords[i1], orig_coords[i2], orig_coords[i3],
- target_coords[i1], target_coords[i2], target_coords[i3])
+ orig_coords[i1],
+ orig_coords[i2],
+ orig_coords[i3],
+ target_coords[i1],
+ target_coords[i2],
+ target_coords[i3],
+ )
median_coords[i2].append(pt)
pt = barycentric_transform(orig_shape_coords[i3],
- orig_coords[i2], orig_coords[i3], orig_coords[i4],
- target_coords[i2], target_coords[i3], target_coords[i4])
+ orig_coords[i2],
+ orig_coords[i3],
+ orig_coords[i4],
+ target_coords[i2],
+ target_coords[i3],
+ target_coords[i4],
+ )
median_coords[i3].append(pt)
pt = barycentric_transform(orig_shape_coords[i4],
- orig_coords[i3], orig_coords[i4], orig_coords[i1],
- target_coords[i3], target_coords[i4], target_coords[i1])
+ orig_coords[i3],
+ orig_coords[i4],
+ orig_coords[i1],
+ target_coords[i3],
+ target_coords[i4],
+ target_coords[i1],
+ )
median_coords[i4].append(pt)
else:
pt = barycentric_transform(orig_shape_coords[i1],
- orig_coords[i3], orig_coords[i1], orig_coords[i2],
- target_coords[i3], target_coords[i1], target_coords[i2])
+ orig_coords[i3],
+ orig_coords[i1],
+ orig_coords[i2],
+ target_coords[i3],
+ target_coords[i1],
+ target_coords[i2],
+ )
median_coords[i1].append(pt)
pt = barycentric_transform(orig_shape_coords[i2],
- orig_coords[i1], orig_coords[i2], orig_coords[i3],
- target_coords[i1], target_coords[i2], target_coords[i3])
+ orig_coords[i1],
+ orig_coords[i2],
+ orig_coords[i3],
+ target_coords[i1],
+ target_coords[i2],
+ target_coords[i3],
+ )
median_coords[i2].append(pt)
pt = barycentric_transform(orig_shape_coords[i3],
- orig_coords[i2], orig_coords[i3], orig_coords[i1],
- target_coords[i2], target_coords[i3], target_coords[i1])
+ orig_coords[i2],
+ orig_coords[i3],
+ orig_coords[i1],
+ target_coords[i2],
+ target_coords[i3],
+ target_coords[i1],
+ )
median_coords[i3].append(pt)
elif mode == 'RELATIVE_EDGE':
@@ -374,7 +468,8 @@ class ShapeTransfer(bpy.types.Operator):
if use_clamp:
# clamp to the same movement as the original
# breaks copy between different scaled meshes.
- len_from = (orig_shape_coords[i] - orig_coords[i]).length
+ len_from = (orig_shape_coords[i] -
+ orig_coords[i]).length
ofs = co - target_coords[i]
ofs.length = len_from
co = target_coords[i] + ofs
@@ -395,7 +490,10 @@ class ShapeTransfer(bpy.types.Operator):
if 1: # swap from/to, means we cant copy to many at once.
if len(objects) != 1:
- self.report({'ERROR'}, "Expected one other selected mesh object to copy from")
+ self.report({'ERROR'},
+ ("Expected one other selected "
+ "mesh object to copy from"))
+
return {'CANCELLED'}
ob_act, objects = objects[0], [ob_act]
@@ -429,11 +527,14 @@ class JoinUVs(bpy.types.Operator):
bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
if not mesh.uv_textures:
- self.report({'WARNING'}, "Object: %s, Mesh: '%s' has no UVs\n" % (obj.name, mesh.name))
+ self.report({'WARNING'},
+ "Object: %s, Mesh: '%s' has no UVs"
+ % (obj.name, mesh.name))
else:
len_faces = len(mesh.faces)
- uv_array = array.array('f', [0.0] * 8) * len_faces # seems to be the fastest way to create an array
+ # seems to be the fastest way to create an array
+ uv_array = array.array('f', [0.0] * 8) * len_faces
mesh.uv_textures.active.data.foreach_get("uv_raw", uv_array)
objects = context.selected_editable_objects[:]
@@ -450,11 +551,18 @@ class JoinUVs(bpy.types.Operator):
mesh_other.tag = True
if len(mesh_other.faces) != len_faces:
- self.report({'WARNING'}, "Object: %s, Mesh: '%s' has %d faces, expected %d\n" % (obj_other.name, mesh_other.name, len(mesh_other.faces), len_faces))
+ self.report({'WARNING'}, "Object: %s, Mesh: "
+ "'%s' has %d faces, expected %d\n"
+ % (obj_other.name,
+ mesh_other.name,
+ len(mesh_other.faces),
+ len_faces),
+ )
else:
uv_other = mesh_other.uv_textures.active
if not uv_other:
- uv_other = mesh_other.uv_textures.new() # should return the texture it adds
+ # should return the texture it adds
+ uv_other = mesh_other.uv_textures.new()
# finally do the copy
uv_other.data.foreach_set("uv_raw", uv_array)
@@ -482,14 +590,18 @@ class MakeDupliFace(bpy.types.Operator):
SCALE_FAC = 0.01
offset = 0.5 * SCALE_FAC
- base_tri = Vector((-offset, -offset, 0.0)), Vector((offset, -offset, 0.0)), Vector((offset, offset, 0.0)), Vector((-offset, offset, 0.0))
+ base_tri = (Vector((-offset, -offset, 0.0)),
+ Vector((+offset, -offset, 0.0)),
+ Vector((+offset, +offset, 0.0)),
+ Vector((-offset, +offset, 0.0)),
+ )
def matrix_to_quat(matrix):
# scale = matrix.median_scale
trans = matrix.to_translation()
rot = matrix.to_3x3() # also contains scale
- return [(b * rot) + trans for b in base_tri]
+ return [(rot * b) + trans for b in base_tri]
scene = bpy.context.scene
linked = {}
for obj in bpy.context.selected_objects:
@@ -498,7 +610,10 @@ class MakeDupliFace(bpy.types.Operator):
linked.setdefault(data, []).append(obj)
for data, objects in linked.items():
- face_verts = [axis for obj in objects for v in matrix_to_quat(obj.matrix_world) for axis in v]
+ face_verts = [axis for obj in objects
+ for v in matrix_to_quat(obj.matrix_world)
+ for axis in v]
+
faces = list(range(len(face_verts) // 3))
mesh = bpy.data.meshes.new(data.name + "_dupli")
@@ -535,7 +650,8 @@ class MakeDupliFace(bpy.types.Operator):
class IsolateTypeRender(bpy.types.Operator):
- '''Hide unselected render objects of same type as active by setting the hide render flag'''
+ '''Hide unselected render objects of same type as active ''' \
+ '''by setting the hide render flag'''
bl_idname = "object.isolate_type_render"
bl_label = "Restrict Render Unselected"
bl_options = {'REGISTER', 'UNDO'}
diff --git a/release/scripts/startup/bl_operators/object_align.py b/release/scripts/startup/bl_operators/object_align.py
index 952a2328ca9..7fd769c40c9 100644
--- a/release/scripts/startup/bl_operators/object_align.py
+++ b/release/scripts/startup/bl_operators/object_align.py
@@ -16,102 +16,109 @@
#
# ##### END GPL LICENSE BLOCK #####
-# <pep8 compliant>
+# <pep8-80 compliant>
import bpy
from mathutils import Vector
+
def GlobalBB_LQ(bb_world):
-
+
# Initialize the variables with the 8th vertex
- left, right, front, back, down, up =\
- bb_world[7][0],\
- bb_world[7][0],\
- bb_world[7][1],\
- bb_world[7][1],\
- bb_world[7][2],\
- bb_world[7][2]
-
+ left, right, front, back, down, up = (bb_world[7][0],
+ bb_world[7][0],
+ bb_world[7][1],
+ bb_world[7][1],
+ bb_world[7][2],
+ bb_world[7][2],
+ )
+
# Test against the other 7 verts
- for i in range (7):
-
+ for i in range(7):
+
# X Range
val = bb_world[i][0]
if val < left:
left = val
-
+
if val > right:
right = val
-
+
# Y Range
val = bb_world[i][1]
if val < front:
front = val
-
+
if val > back:
back = val
-
+
# Z Range
val = bb_world[i][2]
if val < down:
down = val
-
+
if val > up:
up = val
-
+
return (Vector((left, front, up)), Vector((right, back, down)))
+
def GlobalBB_HQ(obj):
-
+
matrix_world = obj.matrix_world.copy()
-
+
# Initialize the variables with the last vertex
-
+
verts = obj.data.vertices
-
- val = verts[-1].co * matrix_world
-
- left, right, front, back, down, up =\
- val[0],\
- val[0],\
- val[1],\
- val[1],\
- val[2],\
- val[2]
-
+
+ val = matrix_world * verts[-1].co
+
+ left, right, front, back, down, up = (val[0],
+ val[0],
+ val[1],
+ val[1],
+ val[2],
+ val[2],
+ )
+
# Test against all other verts
- for i in range (len(verts)-1):
-
- vco = verts[i].co * matrix_world
-
+ for i in range(len(verts) - 1):
+
+ vco = matrix_world * verts[i].co
+
# X Range
val = vco[0]
if val < left:
left = val
-
+
if val > right:
right = val
-
+
# Y Range
val = vco[1]
if val < front:
front = val
-
+
if val > back:
back = val
-
+
# Z Range
val = vco[2]
if val < down:
down = val
-
+
if val > up:
up = val
-
- return (Vector((left, front, up)), Vector((right, back, down)))
+ return Vector((left, front, up)), Vector((right, back, down))
-def align_objects(align_x, align_y, align_z, align_mode, relative_to, bb_quality):
+
+def align_objects(align_x,
+ align_y,
+ align_z,
+ align_mode,
+ relative_to,
+ bb_quality):
cursor = bpy.context.scene.cursor_location
@@ -123,20 +130,20 @@ def align_objects(align_x, align_y, align_z, align_mode, relative_to, bb_quality
objs = []
for obj in bpy.context.selected_objects:
- matrix_world = obj.matrix_world
- bb_world = [Vector(v[:]) * matrix_world for v in obj.bound_box]
+ matrix_world = obj.matrix_world.copy()
+ bb_world = [matrix_world * Vector(v[:]) for v in obj.bound_box]
objs.append((obj, bb_world))
if not objs:
return False
for obj, bb_world in objs:
-
+
if bb_quality:
GBB = GlobalBB_HQ(obj)
else:
GBB = GlobalBB_LQ(bb_world)
-
+
Left_Front_Up = GBB[0]
Right_Back_Down = GBB[1]
@@ -193,13 +200,14 @@ def align_objects(align_x, align_y, align_z, align_mode, relative_to, bb_quality
# Main Loop
for obj, bb_world in objs:
- bb_world = [Vector(v[:]) * obj.matrix_world for v in obj.bound_box]
-
+ matrix_world = obj.matrix_world.copy()
+ bb_world = [matrix_world * Vector(v[:]) for v in obj.bound_box]
+
if bb_quality:
GBB = GlobalBB_HQ(obj)
else:
GBB = GlobalBB_LQ(bb_world)
-
+
Left_Front_Up = GBB[0]
Right_Back_Down = GBB[1]
@@ -339,7 +347,9 @@ class AlignObjects(bpy.types.Operator):
bb_quality = BoolProperty(
name="High Quality",
- description="Enables high quality calculation of the bounding box for perfect results on complex shape meshes with rotation/scale (Slow)",
+ description=("Enables high quality calculation of the "
+ "bounding box for perfect results on complex "
+ "shape meshes with rotation/scale (Slow)"),
default=True)
align_mode = EnumProperty(items=(
@@ -374,7 +384,12 @@ class AlignObjects(bpy.types.Operator):
def execute(self, context):
align_axis = self.align_axis
- ret = align_objects('X' in align_axis, 'Y' in align_axis, 'Z' in align_axis, self.align_mode, self.relative_to, self.bb_quality)
+ ret = align_objects('X' in align_axis,
+ 'Y' in align_axis,
+ 'Z' in align_axis,
+ self.align_mode,
+ self.relative_to,
+ self.bb_quality)
if not ret:
self.report({'WARNING'}, "No objects with bound-box selected")
diff --git a/release/scripts/startup/bl_operators/object_quick_effects.py b/release/scripts/startup/bl_operators/object_quick_effects.py
index 074f204d50e..ef10bfd737d 100644
--- a/release/scripts/startup/bl_operators/object_quick_effects.py
+++ b/release/scripts/startup/bl_operators/object_quick_effects.py
@@ -16,11 +16,16 @@
#
# ##### END GPL LICENSE BLOCK #####
-# <pep8 compliant>
+# <pep8-80 compliant>
from mathutils import Vector
import bpy
-from bpy.props import BoolProperty, EnumProperty, IntProperty, FloatProperty, FloatVectorProperty
+from bpy.props import (BoolProperty,
+ EnumProperty,
+ IntProperty,
+ FloatProperty,
+ FloatVectorProperty,
+ )
def object_ensure_material(obj, mat_name):
@@ -61,7 +66,8 @@ class QuickFur(bpy.types.Operator):
def execute(self, context):
fake_context = bpy.context.copy()
- mesh_objects = [obj for obj in context.selected_objects if obj.type == 'MESH']
+ mesh_objects = [obj for obj in context.selected_objects
+ if obj.type == 'MESH']
if not mesh_objects:
self.report({'ERROR'}, "Select at least one mesh object.")
@@ -92,7 +98,8 @@ class QuickFur(bpy.types.Operator):
psys.settings.child_type = 'INTERPOLATED'
obj.data.materials.append(mat)
- obj.particle_systems[-1].settings.material = len(obj.data.materials)
+ obj.particle_systems[-1].settings.material = \
+ len(obj.data.materials)
return {'FINISHED'}
@@ -149,7 +156,10 @@ class QuickExplode(bpy.types.Operator):
for obj in mesh_objects:
if obj.particle_systems:
- self.report({'ERROR'}, "Object %r already has a particle system" % obj.name)
+ self.report({'ERROR'},
+ "Object %r already has a "
+ "particle system" % obj.name)
+
return {'CANCELLED'}
if self.fade:
@@ -184,9 +194,7 @@ class QuickExplode(bpy.types.Operator):
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"
+ uv = obj.data.uv_textures.new("Explode fade")
explode.particle_uv = uv.name
mat = object_ensure_material(obj, "Explode Fade")
@@ -247,7 +255,7 @@ class QuickExplode(bpy.types.Operator):
def obj_bb_minmax(obj, min_co, max_co):
for i in range(0, 8):
- bb_vec = Vector(obj.bound_box[i]) * obj.matrix_world
+ bb_vec = obj.matrix_world * Vector(obj.bound_box[i])
min_co[0] = min(bb_vec[0], min_co[0])
min_co[1] = min(bb_vec[1], min_co[1])
@@ -262,21 +270,26 @@ class QuickSmoke(bpy.types.Operator):
bl_label = "Quick Smoke"
bl_options = {'REGISTER', 'UNDO'}
- style = EnumProperty(items=(
- ('STREAM', "Stream", ""),
- ('PUFF', "Puff", ""),
- ('FIRE', "Fire", "")),
- name="Smoke Style",
- description="",
- default='STREAM')
-
- show_flows = BoolProperty(name="Render Smoke Objects",
- description="Keep the smoke objects visible during rendering.",
- default=False)
+ style = EnumProperty(
+ items=(('STREAM', "Stream", ""),
+ ('PUFF', "Puff", ""),
+ ('FIRE', "Fire", ""),
+ ),
+ name="Smoke Style",
+ description="",
+ default='STREAM',
+ )
+
+ show_flows = BoolProperty(
+ name="Render Smoke Objects",
+ description="Keep the smoke objects visible during rendering.",
+ default=False,
+ )
def execute(self, context):
fake_context = bpy.context.copy()
- mesh_objects = [obj for obj in context.selected_objects if obj.type == 'MESH']
+ mesh_objects = [obj for obj in context.selected_objects
+ if obj.type == 'MESH']
min_co = Vector((100000.0, 100000.0, 100000.0))
max_co = -min_co
@@ -336,21 +349,25 @@ class QuickSmoke(bpy.types.Operator):
mat.volume.density = 0
mat.volume.density_scale = 5
- mat.texture_slots.add()
- mat.texture_slots[0].texture = bpy.data.textures.new("Smoke Density", 'VOXEL_DATA')
- mat.texture_slots[0].texture.voxel_data.domain_object = obj
- mat.texture_slots[0].use_map_color_emission = False
- mat.texture_slots[0].use_map_density = True
+ tex = bpy.data.textures.new("Smoke Density", 'VOXEL_DATA')
+ tex.voxel_data.domain_object = obj
+
+ tex_slot = mat.texture_slots.add()
+ tex_slot.texture = tex
+ tex_slot.use_map_color_emission = False
+ tex_slot.use_map_density = True
# for fire add a second texture for emission and emission color
if self.style == 'FIRE':
mat.volume.emission = 5
- mat.texture_slots.add()
- mat.texture_slots[1].texture = bpy.data.textures.new("Smoke Heat", 'VOXEL_DATA')
- mat.texture_slots[1].texture.voxel_data.domain_object = obj
- mat.texture_slots[1].texture.use_color_ramp = True
+ tex = bpy.data.textures.new("Smoke Heat", 'VOXEL_DATA')
+ tex.voxel_data.domain_object = obj
+ tex.use_color_ramp = True
+
+ tex_slot = mat.texture_slots.add()
+ tex_slot.texture = tex
- ramp = mat.texture_slots[1].texture.color_ramp
+ ramp = tex.color_ramp
elem = ramp.elements.new(0.333)
elem.color[0] = elem.color[3] = 1
@@ -371,28 +388,38 @@ class QuickFluid(bpy.types.Operator):
bl_label = "Quick Fluid"
bl_options = {'REGISTER', 'UNDO'}
- style = EnumProperty(items=(
- ('INFLOW', "Inflow", ""),
- ('BASIC', "Basic", "")),
+ style = EnumProperty(
+ items=(('INFLOW', "Inflow", ""),
+ ('BASIC', "Basic", ""),
+ ),
name="Fluid Style",
description="",
- default='BASIC')
-
- initial_velocity = FloatVectorProperty(name="Initial Velocity",
- description="Initial velocity of the fluid",
- default=(0.0, 0.0, 0.0), min=-100.0, max=100.0, subtype='VELOCITY')
-
- show_flows = BoolProperty(name="Render Fluid Objects",
- description="Keep the fluid objects visible during rendering.",
- default=False)
-
- start_baking = BoolProperty(name="Start Fluid Bake",
- description="Start baking the fluid immediately after creating the domain object.",
- default=False)
+ default='BASIC',
+ )
+ initial_velocity = FloatVectorProperty(
+ name="Initial Velocity",
+ description="Initial velocity of the fluid",
+ default=(0.0, 0.0, 0.0),
+ min=-100.0,
+ max=100.0,
+ subtype='VELOCITY',
+ )
+ show_flows = BoolProperty(
+ name="Render Fluid Objects",
+ description="Keep the fluid objects visible during rendering.",
+ default=False,
+ )
+ start_baking = BoolProperty(
+ name="Start Fluid Bake",
+ description=("Start baking the fluid immediately "
+ "after creating the domain object"),
+ default=False,
+ )
def execute(self, context):
fake_context = bpy.context.copy()
- mesh_objects = [obj for obj in context.selected_objects if (obj.type == 'MESH' and not 0 in obj.dimensions)]
+ mesh_objects = [obj for obj in context.selected_objects
+ if (obj.type == 'MESH' and not 0.0 in obj.dimensions)]
min_co = Vector((100000, 100000, 100000))
max_co = Vector((-100000, -100000, -100000))
@@ -405,7 +432,8 @@ class QuickFluid(bpy.types.Operator):
# make each selected object a fluid
bpy.ops.object.modifier_add(fake_context, type='FLUID_SIMULATION')
- # fluid has to be before constructive modifiers, so it might not be the last modifier
+ # fluid has to be before constructive modifiers,
+ # so it might not be the last modifier
for mod in obj.modifiers:
if mod.type == 'FLUID_SIMULATION':
break
@@ -429,10 +457,14 @@ class QuickFluid(bpy.types.Operator):
obj = context.active_object
obj.name = "Fluid Domain"
- # give the fluid some room below the flows and scale with initial velocity
+ # give the fluid some room below the flows
+ # and scale with initial velocity
v = 0.5 * self.initial_velocity
obj.location = 0.5 * (max_co + min_co) + Vector((0.0, 0.0, -1.0)) + v
- obj.scale = 0.5 * (max_co - min_co) + Vector((1.0, 1.0, 2.0)) + Vector((abs(v[0]), abs(v[1]), abs(v[2])))
+ obj.scale = (0.5 * (max_co - min_co) +
+ Vector((1.0, 1.0, 2.0)) +
+ Vector((abs(v[0]), abs(v[1]), abs(v[2])))
+ )
# setup smoke domain
bpy.ops.object.modifier_add(type='FLUID_SIMULATION')
diff --git a/release/scripts/startup/bl_operators/object_randomize_transform.py b/release/scripts/startup/bl_operators/object_randomize_transform.py
index 9dc5086086f..b94c4f06cd3 100644
--- a/release/scripts/startup/bl_operators/object_randomize_transform.py
+++ b/release/scripts/startup/bl_operators/object_randomize_transform.py
@@ -16,7 +16,7 @@
#
# ##### END GPL LICENSE BLOCK #####
-# <pep8 compliant>
+# <pep8-80 compliant>
import bpy
@@ -93,40 +93,69 @@ class RandomizeLocRotSize(bpy.types.Operator):
bl_label = "Randomize Transform"
bl_options = {'REGISTER', 'UNDO'}
- random_seed = IntProperty(name="Random Seed",
- description="Seed value for the random generator",
- default=0, min=0, max=1000)
-
- use_delta = BoolProperty(name="Transform Delta",
- description="Randomize delta transform values instead of regular transform", default=False)
-
- use_loc = BoolProperty(name="Randomize Location",
- description="Randomize the location values", default=True)
-
- loc = FloatVectorProperty(name="Location",
- description="Maximun distance the objects can spread over each axis",
- default=(0.0, 0.0, 0.0), min=-100.0, max=100.0, subtype='TRANSLATION')
-
- use_rot = BoolProperty(name="Randomize Rotation",
- description="Randomize the rotation values", default=True)
-
- rot = FloatVectorProperty(name="Rotation",
- description="Maximun rotation over each axis",
- default=(0.0, 0.0, 0.0), min=-180.0, max=180.0, subtype='TRANSLATION')
-
- use_scale = BoolProperty(name="Randomize Scale",
- description="Randomize the scale values", default=True)
-
- scale_even = BoolProperty(name="Scale Even",
- description="Use the same scale value for all axis", default=False)
+ random_seed = IntProperty(
+ name="Random Seed",
+ description="Seed value for the random generator",
+ min=0,
+ max=1000,
+ default=0,
+ )
+ use_delta = BoolProperty(
+ name="Transform Delta",
+ description=("Randomize delta transform values "
+ "instead of regular transform"),
+ default=False,
+ )
+ use_loc = BoolProperty(
+ name="Randomize Location",
+ description="Randomize the location values",
+ default=True,
+ )
+ loc = FloatVectorProperty(
+ name="Location",
+ description=("Maximun distance the objects "
+ "can spread over each axis"),
+ min=-100.0,
+ max=100.0,
+ default=(0.0, 0.0, 0.0),
+ subtype='TRANSLATION',
+ )
+ use_rot = BoolProperty(
+ name="Randomize Rotation",
+ description="Randomize the rotation values",
+ default=True,
+ )
+ rot = FloatVectorProperty(
+ name="Rotation",
+ description="Maximun rotation over each axis",
+ min=-180.0,
+ max=180.0,
+ default=(0.0, 0.0, 0.0),
+ subtype='TRANSLATION',
+ )
+ use_scale = BoolProperty(
+ name="Randomize Scale",
+ description="Randomize the scale values",
+ default=True,
+ )
+ scale_even = BoolProperty(
+ name="Scale Even",
+ description="Use the same scale value for all axis",
+ default=False,
+ )
'''scale_min = FloatProperty(name="Minimun Scale Factor",
description="Lowest scale percentage possible",
default=0.15, min=-1.0, max=1.0, precision=3)'''
- scale = FloatVectorProperty(name="Scale",
- description="Maximum scale randomization over each axis",
- default=(0.0, 0.0, 0.0), min=-100.0, max=100.0, subtype='TRANSLATION')
+ scale = FloatVectorProperty(
+ name="Scale",
+ description="Maximum scale randomization over each axis",
+ min=-100.0,
+ max=100.0,
+ default=(0.0, 0.0, 0.0),
+ subtype='TRANSLATION',
+ )
def execute(self, context):
from math import radians
diff --git a/release/scripts/startup/bl_operators/presets.py b/release/scripts/startup/bl_operators/presets.py
index f3c799c9ac2..fbcc327c3bd 100644
--- a/release/scripts/startup/bl_operators/presets.py
+++ b/release/scripts/startup/bl_operators/presets.py
@@ -16,7 +16,7 @@
#
# ##### END GPL LICENSE BLOCK #####
-# <pep8 compliant>
+# <pep8-80 compliant>
import bpy
@@ -30,8 +30,15 @@ class AddPresetBase():
# bl_label = "Add a Python Preset"
bl_options = {'REGISTER'} # only because invoke_props_popup requires.
- name = bpy.props.StringProperty(name="Name", description="Name of the preset, used to make the path name", maxlen=64, default="")
- remove_active = bpy.props.BoolProperty(default=False, options={'HIDDEN'})
+ name = bpy.props.StringProperty(
+ name="Name",
+ description="Name of the preset, used to make the path name",
+ maxlen=64,
+ )
+ remove_active = bpy.props.BoolProperty(
+ default=False,
+ options={'HIDDEN'},
+ )
@staticmethod
def as_filename(name): # could reuse for other presets
@@ -54,7 +61,10 @@ class AddPresetBase():
filename = self.as_filename(name)
- target_path = bpy.utils.user_resource('SCRIPTS', os.path.join("presets", self.preset_subdir), create=True)
+ target_path = os.path.join("presets", self.preset_subdir)
+ target_path = bpy.utils.user_resource('SCRIPTS',
+ target_path,
+ create=True)
if not target_path:
self.report({'WARNING'}, "Failed to create presets path")
@@ -95,7 +105,9 @@ class AddPresetBase():
filepath = bpy.utils.preset_find(preset_active, self.preset_subdir)
if not filepath:
- filepath = bpy.utils.preset_find(preset_active, self.preset_subdir, display_name=True)
+ filepath = bpy.utils.preset_find(preset_active,
+ self.preset_subdir,
+ display_name=True)
if not filepath:
return {'CANCELLED'}
@@ -133,8 +145,15 @@ class ExecutePreset(bpy.types.Operator):
bl_idname = "script.execute_preset"
bl_label = "Execute a Python Preset"
- filepath = bpy.props.StringProperty(name="Path", description="Path of the Python file to execute", maxlen=512, default="")
- menu_idname = bpy.props.StringProperty(name="Menu ID Name", description="ID name of the menu this was called from", default="")
+ filepath = bpy.props.StringProperty(
+ name="Path",
+ description="Path of the Python file to execute",
+ maxlen=512,
+ )
+ menu_idname = bpy.props.StringProperty(
+ name="Menu ID Name",
+ description="ID name of the menu this was called from",
+ )
def execute(self, context):
from os.path import basename
@@ -182,7 +201,10 @@ class AddPresetSSS(AddPresetBase, bpy.types.Operator):
preset_menu = "MATERIAL_MT_sss_presets"
preset_defines = [
- "material = (bpy.context.material.active_node_material if bpy.context.material.active_node_material else bpy.context.material)"
+ ("material = "
+ "bpy.context.material.active_node_material "
+ "if bpy.context.material.active_node_material "
+ "else bpy.context.material")
]
preset_values = [
@@ -306,7 +328,11 @@ class AddPresetOperator(AddPresetBase, bpy.types.Operator):
bl_label = "Operator Preset"
preset_menu = "WM_MT_operator_presets"
- operator = bpy.props.StringProperty(name="Operator", maxlen=64, options={'HIDDEN'})
+ operator = bpy.props.StringProperty(
+ name="Operator",
+ maxlen=64,
+ options={'HIDDEN'},
+ )
# XXX, not ideal
preset_defines = [
@@ -322,12 +348,15 @@ class AddPresetOperator(AddPresetBase, bpy.types.Operator):
properties_blacklist = bpy.types.Operator.bl_rna.properties.keys()
prefix, suffix = self.operator.split("_OT_", 1)
- operator_rna = getattr(getattr(bpy.ops, prefix.lower()), suffix).get_rna().bl_rna
+ op = getattr(getattr(bpy.ops, prefix.lower()), suffix)
+ operator_rna = op.get_rna().bl_rna
+ del op
ret = []
for prop_id, prop in operator_rna.properties.items():
- if (not (prop.is_hidden or prop.is_skip_save)) and prop_id not in properties_blacklist:
- ret.append("op.%s" % prop_id)
+ if not (prop.is_hidden or prop.is_skip_save):
+ if prop_id not in properties_blacklist:
+ ret.append("op.%s" % prop_id)
return ret
diff --git a/release/scripts/startup/bl_operators/screen_play_rendered_anim.py b/release/scripts/startup/bl_operators/screen_play_rendered_anim.py
index 8699862d24b..a38d817d738 100644
--- a/release/scripts/startup/bl_operators/screen_play_rendered_anim.py
+++ b/release/scripts/startup/bl_operators/screen_play_rendered_anim.py
@@ -1,27 +1,23 @@
-# ***** BEGIN GPL LICENSE BLOCK *****
+# ##### BEGIN GPL LICENSE BLOCK #####
#
-# Script copyright (C) Campbell J Barton
+# 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 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.
#
-# 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.
#
-# 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.
-#
-# ***** END GPL LICENCE BLOCK *****
+# ##### END GPL LICENSE BLOCK #####
-# <pep8 compliant>
+# <pep8-80 compliant>
-# History
-#
# Originally written by Matt Ebb
import bpy
@@ -46,8 +42,10 @@ def guess_player_path(preset):
player_path = "djv_view"
if sys.platform == "darwin":
- # TODO, crummy supporting only 1 version, could find the newest installed version
- test_path = '/Applications/djv-0.8.2.app/Contents/Resources/bin/djv_view'
+ # TODO, crummy supporting only 1 version,
+ # could find the newest installed version
+ test_path = ("/Applications/djv-0.8.2.app"
+ "/Contents/Resources/bin/djv_view")
if os.path.exists(test_path):
player_path = test_path
@@ -59,7 +57,7 @@ def guess_player_path(preset):
elif preset == 'MPLAYER':
player_path = "mplayer"
-
+
else:
player_path = ""
@@ -85,10 +83,10 @@ class PlayRenderedAnim(bpy.types.Operator):
is_movie = rd.is_movie_format
# try and guess a command line if it doesn't exist
- if player_path == '':
+ if player_path == "":
player_path = guess_player_path(preset)
- if is_movie == False and preset in ('FRAMECYCLER', 'RV', 'MPLAYER'):
+ if is_movie == False and preset in {'FRAMECYCLER', 'RV', 'MPLAYER'}:
# replace the number with '#'
file_a = rd.frame_path(frame=0)
@@ -98,11 +96,11 @@ class PlayRenderedAnim(bpy.types.Operator):
while len(file_a) == len(file_b):
frame_tmp = (frame_tmp * 10) + 9
- print(frame_tmp)
file_b = rd.frame_path(frame=frame_tmp)
file_b = rd.frame_path(frame=int(frame_tmp / 10))
- file = "".join((c if file_b[i] == c else "#") for i, c in enumerate(file_a))
+ file = ("".join((c if file_b[i] == c else "#")
+ for i, c in enumerate(file_a)))
else:
# works for movies and images
file = rd.frame_path(frame=scene.frame_start)
@@ -112,10 +110,35 @@ class PlayRenderedAnim(bpy.types.Operator):
cmd = [player_path]
# extra options, fps controls etc.
if preset == 'BLENDER24':
+ # -----------------------------------------------------------------
+ # Check blender is not 2.5x until it supports playback again
+ try:
+ process = subprocess.Popen([player_path, '--version'],
+ stdout=subprocess.PIPE,
+ )
+ except:
+ # ignore and allow the main execution to catch the problem.
+ process = None
+
+ if process is not None:
+ process.wait()
+ out = process.stdout.read()
+ process.stdout.close()
+ out_split = out.strip().split()
+ if out_split[0] == b'Blender':
+ if not out_split[1].startswith(b'2.4'):
+ self.report({'ERROR'},
+ "Blender %s doesn't support playback: %r" %
+ (out_split[1].decode(), player_path))
+ return {'CANCELLED'}
+ del out, out_split
+ del process
+ # -----------------------------------------------------------------
+
opts = ["-a", "-f", str(rd.fps), str(rd.fps_base), file]
cmd.extend(opts)
elif preset == 'DJV':
- opts = [file, "-playback_speed", str(rd.fps)]
+ opts = [file, "-playback_speed", "%d" % int(rd.fps / rd.fps_base)]
cmd.extend(opts)
elif preset == 'FRAMECYCLER':
opts = [file, "%d-%d" % (scene.frame_start, scene.frame_end)]
@@ -128,20 +151,26 @@ class PlayRenderedAnim(bpy.types.Operator):
if is_movie:
opts.append(file)
else:
- opts.append("mf://%s" % file.replace("#", "?"))
- opts += ["-mf", "fps=%.4f" % (rd.fps / rd.fps_base)]
+ opts += [("mf://%s" % file.replace("#", "?")),
+ "-mf",
+ "fps=%.4f" % (rd.fps / rd.fps_base),
+ ]
+
opts += ["-loop", "0", "-really-quiet", "-fs"]
cmd.extend(opts)
else: # 'CUSTOM'
cmd.append(file)
-
- if (player_path == "") or (os.path.exists(player_path)==False):
- self.report({'ERROR'}, "Couldn't find an external animation player")
- else:
- # launch it
- try:
- process = subprocess.Popen(cmd)
- except:
- pass
+
+ # launch it
+ print("Executing command:\n %r" % " ".join(cmd))
+
+ try:
+ process = subprocess.Popen(cmd)
+ except Exception as e:
+ import traceback
+ self.report({'ERROR'},
+ "Couldn't run external animation player with command "
+ "%r\n%s" % (" ".join(cmd), str(e)))
+ return {'CANCELLED'}
return {'FINISHED'}
diff --git a/release/scripts/startup/bl_operators/uvcalc_smart_project.py b/release/scripts/startup/bl_operators/uvcalc_smart_project.py
index 9c3be84b807..851f33bde11 100644
--- a/release/scripts/startup/bl_operators/uvcalc_smart_project.py
+++ b/release/scripts/startup/bl_operators/uvcalc_smart_project.py
@@ -243,7 +243,7 @@ def testNewVecLs2DRotIsBetter(vecs, mat=-1, bestAreaSoFar = -1):
# Do this allong the way
if mat != -1:
- v = vecs[i] = v*mat
+ v = vecs[i] = mat * v
x= v.x
y= v.y
if x<minx: minx= x
@@ -1064,7 +1064,7 @@ def main(context,
f_uv = f.uv
for j, v in enumerate(f.v):
# XXX - note, between mathutils in 2.4 and 2.5 the order changed.
- f_uv[j][:] = (v.co * MatQuat).xy
+ f_uv[j][:] = (MatQuat * v.co).xy
if USER_SHARE_SPACE:
diff --git a/release/scripts/startup/bl_ui/properties_data_empty.py b/release/scripts/startup/bl_ui/properties_data_empty.py
index 5a0d327f90d..42b0af7eaf5 100644
--- a/release/scripts/startup/bl_ui/properties_data_empty.py
+++ b/release/scripts/startup/bl_ui/properties_data_empty.py
@@ -41,11 +41,9 @@ class DATA_PT_empty(DataButtonsPanel, bpy.types.Panel):
layout.prop(ob, "empty_draw_type", text="Display")
if ob.empty_draw_type == 'IMAGE':
- # layout.template_image(ob, "data", None)
layout.template_ID(ob, "data", open="image.open", unlink="image.unlink")
- row = layout.row(align=True)
- row.prop(ob, "color", text="Transparency", index=3, slider=True)
+ layout.prop(ob, "color", text="Transparency", index=3, slider=True)
row = layout.row(align=True)
row.prop(ob, "empty_image_offset", text="Offset X", index=0)
row.prop(ob, "empty_image_offset", text="Offset Y", index=1)
diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py
index 2429ae630c8..4c25d39717c 100644
--- a/release/scripts/startup/bl_ui/properties_data_modifier.py
+++ b/release/scripts/startup/bl_ui/properties_data_modifier.py
@@ -397,6 +397,7 @@ class DATA_PT_modifiers(ModifierButtonsPanel, bpy.types.Panel):
col.operator("object.multires_higher_levels_delete", text="Delete Higher")
col.operator("object.multires_reshape", text="Reshape")
col.operator("object.multires_base_apply", text="Apply Base")
+ col.prop(md, "use_subsurf_uv")
col.prop(md, "show_only_control_edges")
layout.separator()
diff --git a/release/scripts/startup/bl_ui/properties_material.py b/release/scripts/startup/bl_ui/properties_material.py
index 2a52ae23782..296c05d78f5 100644
--- a/release/scripts/startup/bl_ui/properties_material.py
+++ b/release/scripts/startup/bl_ui/properties_material.py
@@ -247,15 +247,17 @@ class MATERIAL_PT_diffuse(MaterialButtonsPanel, bpy.types.Panel):
row.prop(mat, "diffuse_fresnel_factor", text="Factor")
if mat.use_diffuse_ramp:
- layout.separator()
- layout.template_color_ramp(mat, "diffuse_ramp", expand=True)
- layout.separator()
+ col = layout.column()
+ col.active = (not mat.use_shadeless)
+ col.separator()
+ col.template_color_ramp(mat, "diffuse_ramp", expand=True)
+ col.separator()
- row = layout.row()
+ row = col.row()
row.prop(mat, "diffuse_ramp_input", text="Input")
row.prop(mat, "diffuse_ramp_blend", text="Blend")
- layout.prop(mat, "diffuse_ramp_factor", text="Factor")
+ col.prop(mat, "diffuse_ramp_factor", text="Factor")
class MATERIAL_PT_specular(MaterialButtonsPanel, bpy.types.Panel):
diff --git a/release/scripts/startup/bl_ui/properties_world.py b/release/scripts/startup/bl_ui/properties_world.py
index 0272667e754..c577af01374 100644
--- a/release/scripts/startup/bl_ui/properties_world.py
+++ b/release/scripts/startup/bl_ui/properties_world.py
@@ -93,7 +93,7 @@ class WORLD_PT_world(WorldButtonsPanel, bpy.types.Panel):
col.prop(world, "zenith_color")
col.active = world.use_sky_blend
row.column().prop(world, "ambient_color")
-
+
row = layout.row()
row.prop(world, "exposure")
row.prop(world, "color_range")
diff --git a/release/scripts/startup/bl_ui/space_info.py b/release/scripts/startup/bl_ui/space_info.py
index cda37b3119a..f66cee7f431 100644
--- a/release/scripts/startup/bl_ui/space_info.py
+++ b/release/scripts/startup/bl_ui/space_info.py
@@ -60,7 +60,7 @@ class INFO_HT_header(bpy.types.Header):
layout.template_running_jobs()
layout.template_reports_banner()
-
+
row = layout.row(align=True)
row.operator("wm.splash", text="", icon='BLENDER', emboss=False)
row.label(text=scene.statistics())
diff --git a/release/scripts/startup/bl_ui/space_node.py b/release/scripts/startup/bl_ui/space_node.py
index 831fd359782..2088d8798f2 100644
--- a/release/scripts/startup/bl_ui/space_node.py
+++ b/release/scripts/startup/bl_ui/space_node.py
@@ -135,7 +135,7 @@ class NODE_MT_node(bpy.types.Menu):
layout.operator("transform.resize")
layout.separator()
-
+
layout.operator("node.duplicate_move")
layout.operator("node.delete")
layout.operator("node.delete_reconnect")
diff --git a/release/scripts/startup/bl_ui/space_text.py b/release/scripts/startup/bl_ui/space_text.py
index 0fc8d937f66..b787fc5cf75 100644
--- a/release/scripts/startup/bl_ui/space_text.py
+++ b/release/scripts/startup/bl_ui/space_text.py
@@ -16,7 +16,7 @@
#
# ##### END GPL LICENSE BLOCK #####
-# <pep8 compliant>
+# <pep8-80 compliant>
import bpy
@@ -33,19 +33,21 @@ class TEXT_HT_header(bpy.types.Header):
row.template_header()
if context.area.show_menus:
- sub = row.row(align=True)
- sub.menu("TEXT_MT_view")
- sub.menu("TEXT_MT_text")
+ row.menu("TEXT_MT_view")
+ row.menu("TEXT_MT_text")
+
if text:
- sub.menu("TEXT_MT_edit")
- sub.menu("TEXT_MT_format")
+ row.menu("TEXT_MT_edit")
+ row.menu("TEXT_MT_format")
+
+ row.menu("TEXT_MT_templates")
if text and text.is_modified:
- row = layout.row()
- row.alert = True
- row.operator("text.resolve_conflict", text="", icon='HELP')
+ sub = row.row()
+ sub.alert = True
+ sub.operator("text.resolve_conflict", text="", icon='HELP')
- layout.template_ID(st, "text", new="text.new", unlink="text.unlink")
+ row.template_ID(st, "text", new="text.new", unlink="text.unlink")
row = layout.row(align=True)
row.prop(st, "show_line_numbers", text="")
@@ -63,11 +65,13 @@ class TEXT_HT_header(bpy.types.Header):
row = layout.row()
if text.filepath:
if text.is_dirty:
- row.label(text="File: *%s (unsaved)" % text.filepath)
+ row.label(text="File: *%r (unsaved)" % text.filepath)
else:
- row.label(text="File: %s" % text.filepath)
+ row.label(text="File: %r" % text.filepath)
else:
- row.label(text="Text: External" if text.library else "Text: Internal")
+ row.label(text="Text: External"
+ if text.library
+ else "Text: Internal")
class TEXT_PT_properties(bpy.types.Panel):
@@ -150,8 +154,12 @@ class TEXT_MT_view(bpy.types.Menu):
layout.separator()
- layout.operator("text.move", text="Top of File").type = 'FILE_TOP'
- layout.operator("text.move", text="Bottom of File").type = 'FILE_BOTTOM'
+ layout.operator("text.move",
+ text="Top of File",
+ ).type = 'FILE_TOP'
+ layout.operator("text.move",
+ text="Bottom of File",
+ ).type = 'FILE_BOTTOM'
class TEXT_MT_text(bpy.types.Menu):
@@ -185,19 +193,15 @@ class TEXT_MT_text(bpy.types.Menu):
# XXX uiMenuItemO(head, 0, "text.refresh_pyconstraints");
#endif
- layout.separator()
-
- layout.menu("TEXT_MT_templates")
-
class TEXT_MT_templates(bpy.types.Menu):
- '''
- Creates the menu items by scanning scripts/templates
- '''
- bl_label = "Script Templates"
+ bl_label = "Templates"
def draw(self, context):
- self.path_menu(bpy.utils.script_paths("templates"), "text.open", {"internal": True})
+ self.path_menu(bpy.utils.script_paths("templates"),
+ "text.open",
+ {"internal": True},
+ )
class TEXT_MT_edit_select(bpy.types.Menu):
@@ -246,8 +250,12 @@ class TEXT_MT_edit_to3d(bpy.types.Menu):
def draw(self, context):
layout = self.layout
- layout.operator("text.to_3d_object", text="One Object").split_lines = False
- layout.operator("text.to_3d_object", text="One Object Per Line").split_lines = True
+ layout.operator("text.to_3d_object",
+ text="One Object",
+ ).split_lines = False
+ layout.operator("text.to_3d_object",
+ text="One Object Per Line",
+ ).split_lines = True
class TEXT_MT_edit(bpy.types.Menu):
diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py
index 139b3205835..1feb1eec0c5 100644
--- a/release/scripts/startup/bl_ui/space_userpref.py
+++ b/release/scripts/startup/bl_ui/space_userpref.py
@@ -817,12 +817,9 @@ class USERPREF_PT_input(bpy.types.Panel, InputKeyMapPanel):
#sub.prop(view, "wheel_scroll_lines", text="Scroll Lines")
col.separator()
- ''' not implemented yet
sub = col.column()
sub.label(text="NDOF Device:")
- sub.prop(inputs, "ndof_pan_speed", text="Pan Speed")
- sub.prop(inputs, "ndof_rotate_speed", text="Orbit Speed")
- '''
+ sub.prop(inputs, "ndof_sensitivity", text="NDOF Sensitivity")
row.separator()
@@ -881,7 +878,7 @@ class USERPREF_PT_addons(bpy.types.Panel):
if not user_addon_paths:
user_script_path = bpy.utils.user_script_path()
if user_script_path is not None:
- user_addon_paths.append(os.path.join(user_script_path(), "addons"))
+ user_addon_paths.append(os.path.join(user_script_path, "addons"))
user_addon_paths.append(os.path.join(bpy.utils.resource_path('USER'), "scripts", "addons"))
for path in user_addon_paths:
@@ -1020,7 +1017,6 @@ class USERPREF_PT_addons(bpy.types.Panel):
for i in range(4 - tot_row):
split.separator()
-
# Append missing scripts
# First collect scripts that are used but have no script file.
module_names = {mod.__name__ for mod, info in addons}
diff --git a/release/scripts/startup/bl_ui/space_userpref_keymap.py b/release/scripts/startup/bl_ui/space_userpref_keymap.py
index 85764c55304..585c3cffcb9 100644
--- a/release/scripts/startup/bl_ui/space_userpref_keymap.py
+++ b/release/scripts/startup/bl_ui/space_userpref_keymap.py
@@ -271,6 +271,8 @@ class InputKeyMapPanel:
row.prop(kmi, "type", text="", full_event=True)
elif map_type == 'MOUSE':
row.prop(kmi, "type", text="", full_event=True)
+ elif map_type == 'NDOF':
+ row.prop(kmi, "type", text="", full_event=True)
elif map_type == 'TWEAK':
subrow = row.row()
subrow.prop(kmi, "type", text="")
@@ -306,7 +308,7 @@ class InputKeyMapPanel:
sub = split.column()
subrow = sub.row(align=True)
- if map_type == 'KEYBOARD':
+ if map_type in {'KEYBOARD', 'NDOF'}:
subrow.prop(kmi, "type", text="", event=True)
subrow.prop(kmi, "value", text="")
elif map_type == 'MOUSE':
@@ -590,6 +592,9 @@ class WM_OT_keyconfig_export(bpy.types.Operator):
if not self.filepath:
raise Exception("Filepath not set")
+ if not self.filepath.endswith('.py'):
+ self.filepath += '.py'
+
f = open(self.filepath, "w")
if not f:
raise Exception("Could not open file")
diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index 7d35ca9ddb8..f96a758e7ce 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -55,7 +55,7 @@ class VIEW3D_HT_header(bpy.types.Header):
row = layout.row()
# Contains buttons like Mode, Pivot, Manipulator, Layer, Mesh Select Mode...
- row.template_header_3D()
+ row.template_header_3D()
if obj:
# Particle edit
@@ -79,19 +79,22 @@ class VIEW3D_HT_header(bpy.types.Header):
row.prop(toolsettings, "proportional_edit_falloff", text="", icon_only=True)
# Snap
+ snap_element = toolsettings.snap_element
row = layout.row(align=True)
row.prop(toolsettings, "use_snap", text="")
row.prop(toolsettings, "snap_element", text="", icon_only=True)
- if toolsettings.snap_element != 'INCREMENT':
+ if snap_element != 'INCREMENT':
row.prop(toolsettings, "snap_target", text="")
- if obj and obj.mode == 'OBJECT':
- row.prop(toolsettings, "use_snap_align_rotation", text="")
- if toolsettings.snap_element == 'VOLUME':
+ if obj:
+ if obj.mode == 'OBJECT':
+ row.prop(toolsettings, "use_snap_align_rotation", text="")
+ elif obj.mode == 'EDIT':
+ row.prop(toolsettings, "use_snap_self", text="")
+
+ if snap_element == 'VOLUME':
row.prop(toolsettings, "use_snap_peel_object", text="")
- elif toolsettings.snap_element == 'FACE':
+ elif snap_element == 'FACE':
row.prop(toolsettings, "use_snap_project", text="")
- if toolsettings.use_snap_project and obj.mode == 'EDIT':
- row.prop(toolsettings, "use_snap_project_self", text="")
# OpenGL render
row = layout.row(align=True)
@@ -346,6 +349,30 @@ class VIEW3D_MT_view_navigation(bpy.types.Menu):
layout.operator("view3d.fly")
+class VIEW3D_MT_ndof_settings(bpy.types.Menu):
+ bl_label = "3D Mouse Settings"
+
+ def draw(self, context):
+ layout = self.layout
+ input_prefs = context.user_preferences.inputs
+
+ layout.separator()
+ layout.prop(input_prefs, "ndof_sensitivity")
+
+ if context.space_data.type == 'VIEW_3D':
+ layout.separator()
+ layout.prop(input_prefs, "ndof_show_guide")
+
+ layout.separator()
+ layout.label(text="orbit options")
+ layout.prop(input_prefs, "ndof_orbit_invert_axes")
+
+ layout.separator()
+ layout.label(text="fly options")
+ layout.prop(input_prefs, "ndof_fly_helicopter", icon='NDOF_FLY')
+ layout.prop(input_prefs, "ndof_lock_horizon", icon='NDOF_DOM')
+
+
class VIEW3D_MT_view_align(bpy.types.Menu):
bl_label = "Align View"
diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
index 19c3224f138..91cfd22b3d6 100644
--- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
@@ -58,6 +58,7 @@ def draw_gpencil_tools(context, layout):
row = col.row()
row.prop(context.tool_settings, "use_grease_pencil_sessions")
+
# ********** default tools for objectmode ****************
class VIEW3D_PT_tools_objectmode(View3DPanel, bpy.types.Panel):
diff --git a/release/scripts/templates/addon_add_object.py b/release/scripts/templates/addon_add_object.py
index 67e033271f4..98517fd97a0 100644
--- a/release/scripts/templates/addon_add_object.py
+++ b/release/scripts/templates/addon_add_object.py
@@ -35,7 +35,7 @@ def add_object(self, context):
mesh.from_pydata(verts, edges, faces)
# useful for development when the mesh may be invalid.
# mesh.validate(verbose=True)
- add_object_data(context, mesh_data, operator=self)
+ add_object_data(context, mesh, operator=self)
class OBJECT_OT_add_object(bpy.types.Operator, AddObjectHelper):
diff --git a/release/scripts/templates/batch_export.py b/release/scripts/templates/batch_export.py
index aa0e601725b..45d26f4b525 100644
--- a/release/scripts/templates/batch_export.py
+++ b/release/scripts/templates/batch_export.py
@@ -26,7 +26,7 @@ for obj in selection:
# bpy.ops.export_scene.x3d(filepath=fn + ".x3d", use_selection=True)
obj.select = False
-
+
print("written:", fn)
for obj in selection:
diff --git a/release/scripts/templates/ui_menu.py b/release/scripts/templates/ui_menu.py
new file mode 100644
index 00000000000..d3c94b86809
--- /dev/null
+++ b/release/scripts/templates/ui_menu.py
@@ -0,0 +1,49 @@
+import bpy
+
+
+class CustomMenu(bpy.types.Menu):
+ bl_label = "Custom Menu"
+ bl_idname = "OBJECT_MT_custom_menu"
+
+ def draw(self, context):
+ layout = self.layout
+
+ layout.operator("wm.open_mainfile")
+ layout.operator("wm.save_as_mainfile").copy = True
+
+ layout.operator("object.shade_smooth")
+
+ layout.label(text="Hello world!", icon='WORLD_DATA')
+
+ # use an operator enum property to populate a submenu
+ layout.operator_menu_enum("object.select_by_type",
+ property="type",
+ text="Select All by Type...",
+ )
+
+ # call another menu
+ layout.operator("wm.call_menu", text="Unwrap").name = "VIEW3D_MT_uv_map"
+
+
+def draw_item(self, context):
+ layout = self.layout
+ layout.menu(CustomMenu.bl_idname)
+
+
+def register():
+ bpy.utils.register_class(CustomMenu)
+
+ # lets add ourselves to the main header
+ bpy.types.INFO_HT_header.append(draw_item)
+
+
+def unregister():
+ bpy.utils.unregister_class(CustomMenu)
+
+ bpy.types.INFO_HT_header.remove(draw_item)
+
+if __name__ == "__main__":
+ register()
+
+ # The menu can also be called from scripts
+ bpy.ops.wm.call_menu(name=CustomMenu.bl_idname)
diff --git a/release/scripts/templates/ui_menu_simple.py b/release/scripts/templates/ui_menu_simple.py
new file mode 100644
index 00000000000..2129dfd81a4
--- /dev/null
+++ b/release/scripts/templates/ui_menu_simple.py
@@ -0,0 +1,26 @@
+import bpy
+
+
+class SimpleCustomMenu(bpy.types.Menu):
+ bl_label = "Simple Custom Menu"
+ bl_idname = "OBJECT_MT_simple_custom_menu"
+
+ def draw(self, context):
+ layout = self.layout
+
+ layout.operator("wm.open_mainfile")
+ layout.operator("wm.save_as_mainfile")
+
+
+def register():
+ bpy.utils.register_class(SimpleCustomMenu)
+
+
+def unregister():
+ bpy.utils.unregister_class(SimpleCustomMenu)
+
+if __name__ == "__main__":
+ register()
+
+ # The menu can also be called from scripts
+ bpy.ops.wm.call_menu(name=SimpleCustomMenu.bl_idname)
diff --git a/release/scripts/templates/panel_simple.py b/release/scripts/templates/ui_panel_simple.py
index e5bf70cb654..cde6126b626 100644
--- a/release/scripts/templates/panel_simple.py
+++ b/release/scripts/templates/ui_panel_simple.py
@@ -1,8 +1,9 @@
import bpy
-class OBJECT_PT_hello(bpy.types.Panel):
+class HelloWorldPanel(bpy.types.Panel):
bl_label = "Hello World Panel"
+ bl_idname = "OBJECT_PT_hello"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "object"
@@ -22,11 +23,11 @@ class OBJECT_PT_hello(bpy.types.Panel):
def register():
- bpy.utils.register_class(OBJECT_PT_hello)
+ bpy.utils.register_class(HelloWorldPanel)
def unregister():
- bpy.utils.unregister_class(OBJECT_PT_hello)
+ bpy.utils.unregister_class(HelloWorldPanel)
if __name__ == "__main__":
diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h
index 25fb6f9f9ff..18f6ad21333 100644
--- a/source/blender/blenkernel/BKE_blender.h
+++ b/source/blender/blenkernel/BKE_blender.h
@@ -53,7 +53,7 @@ extern "C" {
/* can be left blank, otherwise a,b,c... etc with no quotes */
#define BLENDER_VERSION_CHAR a
/* alpha/beta/rc/release, docs use this */
-#define BLENDER_VERSION_CYCLE release
+#define BLENDER_VERSION_CYCLE beta
struct ListBase;
struct MemFile;
diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h
index 0491116d199..557ce417b14 100644
--- a/source/blender/blenkernel/BKE_curve.h
+++ b/source/blender/blenkernel/BKE_curve.h
@@ -115,5 +115,6 @@ int minmax_curve(struct Curve *cu, float min[3], float max[3]);
int curve_center_median(struct Curve *cu, float cent[3]);
int curve_center_bounds(struct Curve *cu, float cent[3]);
void curve_translate(struct Curve *cu, float offset[3], int do_keys);
+void curve_delete_material_index(struct Curve *cu, int index);
#endif
diff --git a/source/blender/blenkernel/BKE_global.h b/source/blender/blenkernel/BKE_global.h
index d21b0428d76..17876c6ec9d 100644
--- a/source/blender/blenkernel/BKE_global.h
+++ b/source/blender/blenkernel/BKE_global.h
@@ -92,9 +92,6 @@ typedef struct Global {
/* save the allowed windowstate of blender when using -W or -w */
int windowstate;
-
- /* ndof device found ? */
- int ndofdevice;
} Global;
/* **************** GLOBAL ********************* */
@@ -174,5 +171,3 @@ extern Global G;
#endif
#endif
-
-
diff --git a/source/blender/blenkernel/BKE_material.h b/source/blender/blenkernel/BKE_material.h
index c445408609c..88965d12e4a 100644
--- a/source/blender/blenkernel/BKE_material.h
+++ b/source/blender/blenkernel/BKE_material.h
@@ -78,7 +78,7 @@ int object_remove_material_slot(struct Object *ob);
/* rna api */
void material_append_id(struct ID *id, struct Material *ma);
-struct Material *material_pop_id(struct ID *id, int index);
+struct Material *material_pop_id(struct ID *id, int index, int remove_material_slot);
/* rendering */
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index ebf21941706..0a96f8d74be 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -1883,8 +1883,10 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
/* set the DerivedMesh to only copy needed data */
mask= (CustomDataMask)GET_INT_FROM_POINTER(curr->link);
+ /* needMapping check here fixes bug [#28112], otherwise its
+ * possible that it wont be copied */
mask |= append_mask;
- DM_set_only_copy(dm, mask);
+ DM_set_only_copy(dm, mask | (needMapping ? CD_MASK_ORIGINDEX : 0));
/* add cloth rest shape key if need */
if(mask & CD_MASK_CLOTH_ORCO)
diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c
index a184088aa17..57a155987d1 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -1289,6 +1289,7 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, vo
QUATCOPY((float *)&varray[elementsize*curface*3+offset+elementsize*2], tang);
offset += sizeof(float)*4;
}
+ (void)offset;
}
curface++;
if(mface->v4) {
@@ -1329,6 +1330,7 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, vo
QUATCOPY((float *)&varray[elementsize*curface*3+offset+elementsize*2], tang);
offset += sizeof(float)*4;
}
+ (void)offset;
}
curface++;
i++;
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index 202a3f28d9a..eb364af6ff8 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -580,46 +580,47 @@ void addNurbPointsBezier(Nurb *nu, int number)
/* ~~~~~~~~~~~~~~~~~~~~Non Uniform Rational B Spline calculations ~~~~~~~~~~~ */
-static void calcknots(float *knots, short aantal, short order, short type)
-/* knots: number of pnts NOT corrected for cyclic */
-/* type; 0: uniform, 1: endpoints, 2: bezier */
+static void calcknots(float *knots, const short pnts, const short order, const short flag)
{
+ /* knots: number of pnts NOT corrected for cyclic */
+ const int pnts_order= pnts + order;
float k;
- int a, t;
-
- t = aantal+order;
- if(type==0) {
+ int a;
- for(a=0;a<t;a++) {
- knots[a]= (float)a;
- }
- }
- else if(type==1) {
+ switch(flag & (CU_NURB_ENDPOINT|CU_NURB_BEZIER)) {
+ case CU_NURB_ENDPOINT:
k= 0.0;
- for(a=1;a<=t;a++) {
+ for(a=1; a <= pnts_order; a++) {
knots[a-1]= k;
- if(a>=order && a<=aantal) k+= 1.0f;
+ if(a >= order && a <= pnts) k+= 1.0f;
}
- }
- else if(type==2) {
- /* Warning, the order MUST be 2 or 4, if this is not enforced, the displist will be corrupt */
+ break;
+ case CU_NURB_BEZIER:
+ /* Warning, the order MUST be 2 or 4,
+ * if this is not enforced, the displist will be corrupt */
if(order==4) {
k= 0.34;
- for(a=0;a<t;a++) {
+ for(a=0; a < pnts_order; a++) {
knots[a]= floorf(k);
k+= (1.0f/3.0f);
}
}
else if(order==3) {
k= 0.6f;
- for(a=0;a<t;a++) {
- if(a>=order && a<=aantal) k+= 0.5f;
+ for(a=0; a < pnts_order; a++) {
+ if(a >= order && a <= pnts) k+= 0.5f;
knots[a]= floorf(k);
}
}
else {
printf("bez nurb curve order is not 3 or 4, should never happen\n");
}
+ break;
+ default:
+ for(a=0; a < pnts_order; a++) {
+ knots[a]= (float)a;
+ }
+ break;
}
}
@@ -662,7 +663,7 @@ static void makeknots(Nurb *nu, short uv)
calcknots(nu->knotsu, nu->pntsu, nu->orderu, 0); /* cyclic should be uniform */
makecyclicknots(nu->knotsu, nu->pntsu, nu->orderu);
} else {
- calcknots(nu->knotsu, nu->pntsu, nu->orderu, nu->flagu>>1);
+ calcknots(nu->knotsu, nu->pntsu, nu->orderu, nu->flagu);
}
}
else nu->knotsu= NULL;
@@ -675,7 +676,7 @@ static void makeknots(Nurb *nu, short uv)
calcknots(nu->knotsv, nu->pntsv, nu->orderv, 0); /* cyclic should be uniform */
makecyclicknots(nu->knotsv, nu->pntsv, nu->orderv);
} else {
- calcknots(nu->knotsv, nu->pntsv, nu->orderv, nu->flagv>>1);
+ calcknots(nu->knotsv, nu->pntsv, nu->orderv, nu->flagv);
}
}
else nu->knotsv= NULL;
@@ -3259,3 +3260,28 @@ void curve_translate(Curve *cu, float offset[3], int do_keys)
}
}
}
+
+void curve_delete_material_index(Curve *cu, int index)
+{
+ const int curvetype= curve_type(cu);
+
+ if(curvetype == OB_FONT) {
+ struct CharInfo *info= cu->strinfo;
+ int i;
+ for(i= cu->len-1; i >= 0; i--, info++) {
+ if (info->mat_nr && info->mat_nr>=index) {
+ info->mat_nr--;
+ }
+ }
+ }
+ else {
+ Nurb *nu;
+
+ for (nu= cu->nurb.first; nu; nu= nu->next) {
+ if(nu->mat_nr && nu->mat_nr>=index) {
+ nu->mat_nr--;
+ if (curvetype == OB_CURVE) nu->charidx--;
+ }
+ }
+ }
+}
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index 45faba8439c..8d19322c0db 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -466,7 +466,6 @@ static void layerInterp_mdisps(void **sources, float *UNUSED(weights),
MDisps tris[2];
int vindex[4] = {0};
- S = 0;
for(i = 0; i < 2; i++)
for(y = 0; y < 4; y++)
for(x = 0; x < 4; x++)
diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c
index 4f921f005f4..104ce2b3b32 100644
--- a/source/blender/blenkernel/intern/ipo.c
+++ b/source/blender/blenkernel/intern/ipo.c
@@ -518,7 +518,7 @@ static const char *material_adrcodes_to_paths (int adrcode, int *array_index)
return "alpha";
case MA_REF:
- return "diffuse_reflection";
+ return "diffuse_intensity";
case MA_EMIT:
return "emit";
@@ -527,7 +527,7 @@ static const char *material_adrcodes_to_paths (int adrcode, int *array_index)
return "ambient";
case MA_SPEC:
- return "specular_reflection";
+ return "specular_intensity";
case MA_HARD:
return "specular_hardness";
@@ -551,13 +551,13 @@ static const char *material_adrcodes_to_paths (int adrcode, int *array_index)
return "raytrace_mirror.fresnel";
case MA_FRESMIRI:
- return "raytrace_mirror.fresnel_fac";
+ return "raytrace_mirror.fresnel_factor";
case MA_FRESTRA:
return "raytrace_transparency.fresnel";
case MA_FRESTRAI:
- return "raytrace_transparency.fresnel_fac";
+ return "raytrace_transparency.fresnel_factor";
case MA_ADD:
return "halo.add";
diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c
index 8b0cfb1d156..0964c66fecd 100644
--- a/source/blender/blenkernel/intern/key.c
+++ b/source/blender/blenkernel/intern/key.c
@@ -474,20 +474,20 @@ static int setkeys(float fac, ListBase *lb, KeyBlock *k[], float *t, int cycl)
}
-static void flerp(int aantal, float *in, float *f0, float *f1, float *f2, float *f3, float *t)
+static void flerp(int tot, float *in, float *f0, float *f1, float *f2, float *f3, float *t)
{
int a;
- for(a=0; a<aantal; a++) {
+ for(a=0; a<tot; a++) {
in[a]= t[0]*f0[a]+t[1]*f1[a]+t[2]*f2[a]+t[3]*f3[a];
}
}
-static void rel_flerp(int aantal, float *in, float *ref, float *out, float fac)
+static void rel_flerp(int tot, float *in, float *ref, float *out, float fac)
{
int a;
- for(a=0; a<aantal; a++) {
+ for(a=0; a<tot; a++) {
in[a]-= fac*(ref[a]-out[a]);
}
}
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index 962c7fd5e86..9c455e84109 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -61,7 +61,7 @@
#include "BKE_material.h"
#include "BKE_mesh.h"
#include "BKE_node.h"
-
+#include "BKE_curve.h"
#include "GPU_material.h"
@@ -515,6 +515,21 @@ short *give_totcolp_id(ID *id)
return NULL;
}
+void data_delete_material_index_id(ID *id, int index)
+{
+ switch(GS(id->name)) {
+ case ID_ME:
+ mesh_delete_material_index((Mesh *)id, index);
+ break;
+ case ID_CU:
+ curve_delete_material_index((Curve *)id, index);
+ break;
+ case ID_MB:
+ /* meta-elems dont have materials atm */
+ break;
+ }
+}
+
void material_append_id(ID *id, Material *ma)
{
Material ***matar;
@@ -532,7 +547,7 @@ void material_append_id(ID *id, Material *ma)
}
}
-Material *material_pop_id(ID *id, int index)
+Material *material_pop_id(ID *id, int index, int remove_material_slot)
{
Material *ret= NULL;
Material ***matar;
@@ -540,27 +555,36 @@ Material *material_pop_id(ID *id, int index)
short *totcol= give_totcolp_id(id);
if(index >= 0 && index < (*totcol)) {
ret= (*matar)[index];
- id_us_min((ID *)ret);
- if(*totcol <= 1) {
- *totcol= 0;
- MEM_freeN(*matar);
- *matar= NULL;
- }
- else {
- Material **mat;
-
- if(index + 1 != (*totcol))
- memmove((*matar), (*matar) + 1, sizeof(void *) * ((*totcol) - (index + 1)));
+ id_us_min((ID *)ret);
- (*totcol)--;
-
- mat= MEM_callocN(sizeof(void *) * (*totcol), "newmatar");
- memcpy(mat, *matar, sizeof(void *) * (*totcol));
- MEM_freeN(*matar);
+ if (remove_material_slot) {
+ if(*totcol <= 1) {
+ *totcol= 0;
+ MEM_freeN(*matar);
+ *matar= NULL;
+ }
+ else {
+ Material **mat;
+ if(index + 1 != (*totcol))
+ memmove((*matar)+index, (*matar)+(index+1), sizeof(void *) * ((*totcol) - (index + 1)));
+
+ (*totcol)--;
+
+ mat= MEM_callocN(sizeof(void *) * (*totcol), "newmatar");
+ memcpy(mat, *matar, sizeof(void *) * (*totcol));
+ MEM_freeN(*matar);
+
+ *matar= mat;
+ test_object_materials(id);
+ }
- *matar= mat;
- test_object_materials(id);
+ /* decrease mat_nr index */
+ data_delete_material_index_id(id, index);
}
+
+ /* don't remove material slot, only clear it*/
+ else
+ (*matar)[index]= NULL;
}
}
@@ -1025,8 +1049,6 @@ int object_remove_material_slot(Object *ob)
{
Material *mao, ***matarar;
Object *obt;
- Curve *cu;
- Nurb *nu;
short *totcolp;
int a, actcol;
@@ -1086,23 +1108,8 @@ int object_remove_material_slot(Object *ob)
}
/* check indices from mesh */
-
- if(ob->type==OB_MESH) {
- Mesh *me= get_mesh(ob);
- mesh_delete_material_index(me, actcol-1);
- freedisplist(&ob->disp);
- }
- else if ELEM(ob->type, OB_CURVE, OB_SURF) {
- cu= ob->data;
- nu= cu->nurb.first;
-
- while(nu) {
- if(nu->mat_nr && nu->mat_nr>=actcol-1) {
- nu->mat_nr--;
- if (ob->type == OB_CURVE) nu->charidx--;
- }
- nu= nu->next;
- }
+ if (ELEM4(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT)) {
+ data_delete_material_index_id((ID *)ob->data, actcol-1);
freedisplist(&ob->disp);
}
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index 45a60b842a7..32819226361 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -1254,10 +1254,10 @@ void mesh_to_curve(Scene *scene, Object *ob)
void mesh_delete_material_index(Mesh *me, int index)
{
+ MFace *mf;
int i;
- for (i=0; i<me->totface; i++) {
- MFace *mf = &((MFace*) me->mface)[i];
+ for (i=0, mf=me->mface; i<me->totface; i++, mf++) {
if (mf->mat_nr && mf->mat_nr>=index)
mf->mat_nr--;
}
diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c
index d833c184274..88a670ecb22 100644
--- a/source/blender/blenkernel/intern/multires.c
+++ b/source/blender/blenkernel/intern/multires.c
@@ -465,12 +465,13 @@ static DerivedMesh *multires_dm_create_local(Object *ob, DerivedMesh *dm, int lv
return multires_dm_create_from_derived(&mmd, 1, dm, ob, 0, 0);
}
-static DerivedMesh *subsurf_dm_create_local(Object *ob, DerivedMesh *dm, int lvl, int simple, int optimal)
+static DerivedMesh *subsurf_dm_create_local(Object *ob, DerivedMesh *dm, int lvl, int simple, int optimal, int plain_uv)
{
SubsurfModifierData smd= {{NULL}};
smd.levels = smd.renderLevels = lvl;
- smd.flags |= eSubsurfModifierFlag_SubsurfUv;
+ if(!plain_uv)
+ smd.flags |= eSubsurfModifierFlag_SubsurfUv;
if(simple)
smd.subdivType = ME_SIMPLE_SUBSURF;
if(optimal)
@@ -591,7 +592,7 @@ void multiresModifier_base_apply(MultiresModifierData *mmd, Object *ob)
/* subdivide the mesh to highest level without displacements */
cddm = CDDM_from_mesh(me, NULL);
DM_set_only_copy(cddm, CD_MASK_BAREMESH);
- origdm = subsurf_dm_create_local(ob, cddm, totlvl, 0, 0);
+ origdm = subsurf_dm_create_local(ob, cddm, totlvl, 0, 0, mmd->flags & eMultiresModifierFlag_PlainUv);
cddm->release(cddm);
/* calc disps */
@@ -626,7 +627,7 @@ static void multires_subdivide(MultiresModifierData *mmd, Object *ob, int totlvl
/* create subsurf DM from original mesh at high level */
cddm = CDDM_from_mesh(me, NULL);
DM_set_only_copy(cddm, CD_MASK_BAREMESH);
- highdm = subsurf_dm_create_local(ob, cddm, totlvl, simple, 0);
+ highdm = subsurf_dm_create_local(ob, cddm, totlvl, simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv);
/* create multires DM from original mesh at low level */
lowdm = multires_dm_create_local(ob, cddm, lvl, lvl, simple);
@@ -830,7 +831,7 @@ static void multiresModifier_update(DerivedMesh *dm)
else cddm = CDDM_from_mesh(me, NULL);
DM_set_only_copy(cddm, CD_MASK_BAREMESH);
- highdm = subsurf_dm_create_local(ob, cddm, totlvl, mmd->simple, 0);
+ highdm = subsurf_dm_create_local(ob, cddm, totlvl, mmd->simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv);
/* create multires DM from original mesh and displacements */
lowdm = multires_dm_create_local(ob, cddm, lvl, totlvl, mmd->simple);
@@ -884,7 +885,7 @@ static void multiresModifier_update(DerivedMesh *dm)
else cddm = CDDM_from_mesh(me, NULL);
DM_set_only_copy(cddm, CD_MASK_BAREMESH);
- subdm = subsurf_dm_create_local(ob, cddm, mmd->totlvl, mmd->simple, 0);
+ subdm = subsurf_dm_create_local(ob, cddm, mmd->totlvl, mmd->simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv);
cddm->release(cddm);
multiresModifier_disp_run(dm, me, 1, 0, subdm->getGridData(subdm), mmd->totlvl);
@@ -927,7 +928,8 @@ DerivedMesh *multires_dm_create_from_derived(MultiresModifierData *mmd, int loca
return dm;
result = subsurf_dm_create_local(ob, dm, lvl,
- mmd->simple, mmd->flags & eMultiresModifierFlag_ControlEdges);
+ mmd->simple, mmd->flags & eMultiresModifierFlag_ControlEdges,
+ mmd->flags & eMultiresModifierFlag_PlainUv);
if(!local_mmd) {
ccgdm = (CCGDerivedMesh*)result;
@@ -1633,7 +1635,7 @@ static void multires_apply_smat(Scene *scene, Object *ob, float smat[3][3])
MEM_freeN(vertCos);
/* scaled ccgDM for tangent space of object with applied scale */
- dm= subsurf_dm_create_local(ob, cddm, high_mmd.totlvl, high_mmd.simple, 0);
+ dm= subsurf_dm_create_local(ob, cddm, high_mmd.totlvl, high_mmd.simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv);
cddm->release(cddm);
/*numGrids= dm->getNumGrids(dm);*/ /*UNUSED*/
diff --git a/source/blender/blenkernel/intern/seqeffects.c b/source/blender/blenkernel/intern/seqeffects.c
index fbb5a77fa04..8c19b0c15c3 100644
--- a/source/blender/blenkernel/intern/seqeffects.c
+++ b/source/blender/blenkernel/intern/seqeffects.c
@@ -2373,7 +2373,7 @@ static void RVBlurBitmap2_float ( float* map, int width,int height,
/* Blancmange (bmange@airdmhor.gen.nz) */
k = -1.0f/(2.0f*(float)M_PI*blur*blur);
- fval=0;
+
for (ix = 0;ix< halfWidth;ix++){
weight = (float)exp(k*(ix*ix));
filter[halfWidth - ix] = weight;
diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c
index da329503c9f..2c507370288 100644
--- a/source/blender/blenkernel/intern/text.c
+++ b/source/blender/blenkernel/intern/text.c
@@ -400,7 +400,13 @@ Text *add_text(const char *file, const char *relpath)
llen++;
}
- if (llen!=0 || ta->nlines==0) {
+ /* create new line in cases:
+ - rest of line (if last line in file hasn't got \n terminator).
+ in this case content of such line would be used to fill text line buffer
+ - file is empty. in this case new line is needed to start editing from.
+ - last characted in buffer is \n. in this case new line is needed to
+ deal with newline at end of file. (see [#28087]) (sergey) */
+ if (llen!=0 || ta->nlines==0 || buffer[len-1]=='\n') {
tmp= (TextLine*) MEM_mallocN(sizeof(TextLine), "textline");
tmp->line= (char*) MEM_mallocN(llen+1, "textline_string");
tmp->format= NULL;
@@ -1417,6 +1423,8 @@ void txt_insert_buf(Text *text, const char *in_buffer)
}
undoing= u;
+
+ (void)count;
}
/******************/
diff --git a/source/blender/blenlib/intern/BLI_args.c b/source/blender/blenlib/intern/BLI_args.c
index 7bc93a3d3a0..5f31565d65b 100644
--- a/source/blender/blenlib/intern/BLI_args.c
+++ b/source/blender/blenlib/intern/BLI_args.c
@@ -290,8 +290,10 @@ void BLI_argsParse(struct bArgs *ba, int pass, BA_ArgCallback default_cb, void *
}
i += retval;
} else if (retval == -1){
- if (a->key->pass != -1)
- ba->passes[i] = pass;
+ if (a) {
+ if (a->key->pass != -1)
+ ba->passes[i] = pass;
+ }
break;
}
}
diff --git a/source/blender/blenlib/intern/pbvh.c b/source/blender/blenlib/intern/pbvh.c
index 85d79ae3b85..0613765b868 100644
--- a/source/blender/blenlib/intern/pbvh.c
+++ b/source/blender/blenlib/intern/pbvh.c
@@ -26,7 +26,6 @@
-
#include "DNA_meshdata_types.h"
#include "MEM_guardedalloc.h"
@@ -85,25 +84,61 @@ struct PBVHNode {
/* Opaque handle for drawing code */
void *draw_buffers;
- int *vert_indices;
-
/* Voxel bounds */
BB vb;
BB orig_vb;
- /* For internal nodes */
+ /* For internal nodes, the offset of the children in the PBVH
+ 'nodes' array. */
int children_offset;
- /* Pointer into bvh prim_indices */
- int *prim_indices;
- int *face_vert_indices;
+ /* Pointer into the PBVH prim_indices array and the number of
+ primitives used by this leaf node.
+ Used for leaf nodes in both mesh- and multires-based PBVHs.
+ */
+ int *prim_indices;
unsigned int totprim;
+
+ /* Array of indices into the mesh's MVert array. Contains the
+ indices of all vertices used by faces that are within this
+ node's bounding box.
+
+ Note that a vertex might be used by a multiple faces, and
+ these faces might be in different leaf nodes. Such a vertex
+ will appear in the vert_indices array of each of those leaf
+ nodes.
+
+ In order to support cases where you want access to multiple
+ nodes' vertices without duplication, the vert_indices array
+ is ordered such that the first part of the array, up to
+ index 'uniq_verts', contains "unique" vertex indices. These
+ vertices might not be truly unique to this node, but if
+ they appear in another node's vert_indices array, they will
+ be above that node's 'uniq_verts' value.
+
+ Used for leaf nodes in a mesh-based PBVH (not multires.)
+ */
+ int *vert_indices;
unsigned int uniq_verts, face_verts;
- char flag;
+ /* An array mapping face corners into the vert_indices
+ array. The array is sized to match 'totprim', and each of
+ the face's corners gets an index into the vert_indices
+ array, in the same order as the corners in the original
+ MFace. The fourth value should not be used if the original
+ face is a triangle.
+
+ Used for leaf nodes in a mesh-based PBVH (not multires.)
+ */
+ int (*face_vert_indices)[4];
+
+ /* Indicates whether this node is a leaf or not; also used for
+ marking various updates that need to be applied. */
+ PBVHNodeFlags flag : 8;
- float tmin; // used for raycasting, is how close bb is to the ray point
+ /* Used for raycasting: how close bb is to the ray point. */
+ float tmin;
int proxy_count;
PBVHProxyNode* proxies;
@@ -339,15 +374,15 @@ static void build_mesh_leaf_node(PBVH *bvh, PBVHNode *node)
node->uniq_verts = node->face_verts = 0;
totface= node->totprim;
- node->face_vert_indices = MEM_callocN(sizeof(int) *
- 4*totface, "bvh node face vert indices");
+ node->face_vert_indices = MEM_callocN(sizeof(int) * 4*totface,
+ "bvh node face vert indices");
for(i = 0; i < totface; ++i) {
MFace *f = bvh->faces + node->prim_indices[i];
int sides = f->v4 ? 4 : 3;
for(j = 0; j < sides; ++j) {
- node->face_vert_indices[i*4 + j]=
+ node->face_vert_indices[i][j]=
map_insert_vert(bvh, map, &node->face_verts,
&node->uniq_verts, (&f->v1)[j]);
}
@@ -373,9 +408,17 @@ static void build_mesh_leaf_node(PBVH *bvh, PBVHNode *node)
BLI_ghashIterator_free(iter);
- for(i = 0; i < totface*4; ++i)
- if(node->face_vert_indices[i] < 0)
- node->face_vert_indices[i]= -node->face_vert_indices[i] + node->uniq_verts - 1;
+ for(i = 0; i < totface; ++i) {
+ MFace *f = bvh->faces + node->prim_indices[i];
+ int sides = f->v4 ? 4 : 3;
+
+ for(j = 0; j < sides; ++j) {
+ if(node->face_vert_indices[i][j] < 0)
+ node->face_vert_indices[i][j]=
+ -node->face_vert_indices[i][j] +
+ node->uniq_verts - 1;
+ }
+ }
if(!G.background) {
node->draw_buffers =
@@ -1340,20 +1383,20 @@ int BLI_pbvh_node_raycast(PBVH *bvh, PBVHNode *node, float (*origco)[3],
if(bvh->faces) {
MVert *vert = bvh->verts;
int *faces= node->prim_indices;
- int *face_verts= node->face_vert_indices;
int totface= node->totprim;
int i;
for(i = 0; i < totface; ++i) {
MFace *f = bvh->faces + faces[i];
+ int *face_verts = node->face_vert_indices[i];
if(origco) {
/* intersect with backuped original coordinates */
hit |= ray_face_intersection(ray_start, ray_normal,
- origco[face_verts[i*4+0]],
- origco[face_verts[i*4+1]],
- origco[face_verts[i*4+2]],
- f->v4? origco[face_verts[i*4+3]]: NULL,
+ origco[face_verts[0]],
+ origco[face_verts[1]],
+ origco[face_verts[2]],
+ f->v4? origco[face_verts[3]]: NULL,
dist);
}
else {
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 43c1defdb96..050ceda0bf4 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -3163,7 +3163,7 @@ static void lib_link_particlesettings(FileData *fd, Main *main)
if(part->effector_weights)
part->effector_weights->group = newlibadr(fd, part->id.lib, part->effector_weights->group);
- if(part->dupliweights.first) {
+ if(part->dupliweights.first && part->dup_group) {
int index_ok = 0;
/* check for old files without indices (all indexes 0) */
dw = part->dupliweights.first;
@@ -3194,6 +3194,9 @@ static void lib_link_particlesettings(FileData *fd, Main *main)
dw->ob = newlibadr(fd, part->id.lib, dw->ob);
}
}
+ else {
+ part->dupliweights.first = part->dupliweights.last = NULL;
+ }
if(part->boids) {
BoidState *state = part->boids->states.first;
diff --git a/source/blender/collada/MaterialExporter.cpp b/source/blender/collada/MaterialExporter.cpp
index a44fa6802f2..9d29177578d 100644
--- a/source/blender/collada/MaterialExporter.cpp
+++ b/source/blender/collada/MaterialExporter.cpp
@@ -37,12 +37,36 @@ MaterialsExporter::MaterialsExporter(COLLADASW::StreamWriter *sw): COLLADASW::Li
void MaterialsExporter::exportMaterials(Scene *sce, bool export_selected)
{
- openLibrary();
+ if(hasMaterials(sce)) {
+ openLibrary();
- MaterialFunctor mf;
- mf.forEachMaterialInScene<MaterialsExporter>(sce, *this, export_selected);
+ MaterialFunctor mf;
+ mf.forEachMaterialInScene<MaterialsExporter>(sce, *this, export_selected);
- closeLibrary();
+ closeLibrary();
+ }
+}
+
+
+bool MaterialsExporter::hasMaterials(Scene *sce)
+{
+ Base *base = (Base *)sce->base.first;
+
+ while(base) {
+ Object *ob= base->object;
+ int a;
+ for(a = 0; a < ob->totcol; a++)
+ {
+ Material *ma = give_current_material(ob, a+1);
+
+ // no material, but check all of the slots
+ if (!ma) continue;
+
+ return true;
+ }
+ base= base->next;
+ }
+ return false;
}
void MaterialsExporter::operator()(Material *ma, Object *ob)
diff --git a/source/blender/collada/MaterialExporter.h b/source/blender/collada/MaterialExporter.h
index 0a7a276d857..c080e4b0596 100644
--- a/source/blender/collada/MaterialExporter.h
+++ b/source/blender/collada/MaterialExporter.h
@@ -51,6 +51,9 @@ public:
MaterialsExporter(COLLADASW::StreamWriter *sw);
void exportMaterials(Scene *sce, bool export_selected);
void operator()(Material *ma, Object *ob);
+
+private:
+ bool hasMaterials(Scene *sce);
};
// used in forEachMaterialInScene
diff --git a/source/blender/editors/armature/editarmature.c b/source/blender/editors/armature/editarmature.c
index 20352206121..628cdbf21e9 100644
--- a/source/blender/editors/armature/editarmature.c
+++ b/source/blender/editors/armature/editarmature.c
@@ -1478,10 +1478,8 @@ static int armature_select_linked_invoke(bContext *C, wmOperator *op, wmEvent *e
bArmature *arm;
EditBone *bone, *curBone, *next;
int extend= RNA_boolean_get(op->ptr, "extend");
- ARegion *ar;
Object *obedit= CTX_data_edit_object(C);
arm= obedit->data;
- ar= CTX_wm_region(C);
view3d_operator_needs_opengl(C);
diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index 06d88b16fa8..210f36ca074 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -3432,7 +3432,6 @@ static int convertspline(short type, Nurb *nu)
nu->type = CU_NURBS;
nu->orderu= 4;
nu->flagu &= CU_NURB_CYCLIC; /* disable all flags except for cyclic */
- nu->flagu |= CU_NURB_BEZIER;
nurbs_knot_calc_u(nu);
a= nu->pntsu*nu->pntsv;
bp= nu->bp;
@@ -6544,12 +6543,15 @@ Nurb *add_nurbs_primitive(bContext *C, float mat[4][4], int type, int newob)
BLI_assert(!"invalid nurbs type");
return NULL;
}
-
- /* always do: */
- nu->flag |= CU_SMOOTH;
-
- test2DNurb(nu);
-
+
+ BLI_assert(nu != NULL);
+
+ if(nu) { /* should always be set */
+ nu->flag |= CU_SMOOTH;
+
+ test2DNurb(nu);
+ }
+
return nu;
}
diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c
index f4da734473d..28a54b20277 100644
--- a/source/blender/editors/gpencil/gpencil_paint.c
+++ b/source/blender/editors/gpencil/gpencil_paint.c
@@ -1617,6 +1617,18 @@ static int gpencil_draw_modal (bContext *C, wmOperator *op, wmEvent *event)
tGPsdata *p= op->customdata;
int estate = OPERATOR_PASS_THROUGH; /* default exit state - not handled, so let others have a share of the pie */
+ // if (event->type == NDOF_MOTION)
+ // return OPERATOR_PASS_THROUGH;
+ // -------------------------------
+ // [mce] Not quite what I was looking
+ // for, but a good start! GP continues to
+ // draw on the screen while the 3D mouse
+ // moves the viewpoint. Problem is that
+ // the stroke is converted to 3D only after
+ // it is finished. This approach should work
+ // better in tools that immediately apply
+ // in 3D space.
+
//printf("\tGP - handle modal event...\n");
/* exit painting mode (and/or end current stroke) */
diff --git a/source/blender/editors/include/BIF_glutil.h b/source/blender/editors/include/BIF_glutil.h
index c9615204607..27bd31c20ff 100644
--- a/source/blender/editors/include/BIF_glutil.h
+++ b/source/blender/editors/include/BIF_glutil.h
@@ -52,6 +52,8 @@ void fdrawXORcirc(float xofs, float yofs, float rad);
/* glStipple defines */
extern unsigned char stipple_halftone[128];
extern unsigned char stipple_quarttone[128];
+extern unsigned char stipple_diag_stripes_pos[128];
+extern unsigned char stipple_diag_stripes_neg[128];
/**
* Draw a lined (non-looping) arc with the given
diff --git a/source/blender/editors/include/ED_transform.h b/source/blender/editors/include/ED_transform.h
index d4d7f971b74..00ae7dda2e3 100644
--- a/source/blender/editors/include/ED_transform.h
+++ b/source/blender/editors/include/ED_transform.h
@@ -148,6 +148,7 @@ void BIF_selectOrientation(void);
#define P_ALIGN_SNAP (P_GEO_SNAP|(1 << 5))
#define P_CONSTRAINT (1 << 6)
#define P_OPTIONS (1 << 7)
+#define P_CORRECT_UV (1 << 8)
void Transform_Properties(struct wmOperatorType *ot, int flags);
diff --git a/source/blender/editors/interface/interface_anim.c b/source/blender/editors/interface/interface_anim.c
index 75e7ee701a2..d9691819b29 100644
--- a/source/blender/editors/interface/interface_anim.c
+++ b/source/blender/editors/interface/interface_anim.c
@@ -1,3 +1,27 @@
+/*
+ * $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):
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
/** \file blender/editors/interface/interface_anim.c
* \ingroup edinterface
*/
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index e9ec4ccc66d..c5275ea98b5 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -1879,7 +1879,6 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle
if(but->autocomplete_func || data->searchbox) {
changed= ui_textedit_autocomplete(C, but, data);
update= 1; /* do live update for tab key */
- retval= WM_UI_HANDLER_BREAK;
}
/* the hotkey here is not well defined, was G.qual so we check all */
else if(event->shift || event->ctrl || event->alt || event->oskey) {
@@ -2325,8 +2324,8 @@ static float ui_numedit_apply_snapf(uiBut *but, float tempf, float softmin, floa
if(fac != 1.0f) {
/* snap in unit-space */
tempf /= fac;
- softmin /= fac;
- softmax /= fac;
+ /* softmin /= fac; */ /* UNUSED */
+ /* softmax /= fac; */ /* UNUSED */
softrange /= fac;
}
@@ -3469,13 +3468,13 @@ static int ui_numedit_but_CURVE(uiBut *but, uiHandleButtonData *data, int snap,
CurveMapping *cumap= (CurveMapping*)but->poin;
CurveMap *cuma= cumap->cm+cumap->cur;
CurveMapPoint *cmp= cuma->curve;
- float fx, fy, zoomx, zoomy, offsx, offsy;
+ float fx, fy, zoomx, zoomy /*, offsx, offsy */ /* UNUSED */;
int a, changed= 0;
zoomx= (but->x2-but->x1)/(cumap->curr.xmax-cumap->curr.xmin);
zoomy= (but->y2-but->y1)/(cumap->curr.ymax-cumap->curr.ymin);
- offsx= cumap->curr.xmin;
- offsy= cumap->curr.ymin;
+ /* offsx= cumap->curr.xmin; */
+ /* offsy= cumap->curr.ymin; */
if(snap) {
float d[2];
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index 79a90fb9d1d..2f0bcc9d5b4 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -149,10 +149,10 @@ typedef struct uiLayoutItemBx {
uiBut *roundbox;
} uiLayoutItemBx;
-typedef struct uiLayoutItemSplt {
+typedef struct uiLayoutItemSplit {
uiLayout litem;
float percentage;
-} uiLayoutItemSplt;
+} uiLayoutItemSplit;
typedef struct uiLayoutItemRoot {
uiLayout litem;
@@ -1615,7 +1615,7 @@ static void ui_litem_layout_row(uiLayout *litem)
int x, y, w, tot, totw, neww, itemw, minw, itemh, offset;
int fixedw, freew, fixedx, freex, flag= 0, lastw= 0;
- x= litem->x;
+ /* x= litem->x; */ /* UNUSED */
y= litem->y;
w= litem->w;
totw= 0;
@@ -2020,7 +2020,7 @@ static void ui_litem_estimate_split(uiLayout *litem)
static void ui_litem_layout_split(uiLayout *litem)
{
- uiLayoutItemSplt *split= (uiLayoutItemSplt*)litem;
+ uiLayoutItemSplit *split= (uiLayoutItemSplit*)litem;
uiItem *item;
float percentage;
const int tot= BLI_countlist(&litem->items);
@@ -2242,9 +2242,9 @@ uiLayout *uiLayoutOverlap(uiLayout *layout)
uiLayout *uiLayoutSplit(uiLayout *layout, float percentage, int align)
{
- uiLayoutItemSplt *split;
+ uiLayoutItemSplit *split;
- split= MEM_callocN(sizeof(uiLayoutItemSplt), "uiLayoutItemSplt");
+ split= MEM_callocN(sizeof(uiLayoutItemSplit), "uiLayoutItemSplit");
split->litem.item.type= ITEM_LAYOUT_SPLIT;
split->litem.root= layout->root;
split->litem.align= align;
diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c
index 9ed3cabb4cb..3b20533dcd4 100644
--- a/source/blender/editors/interface/interface_panel.c
+++ b/source/blender/editors/interface/interface_panel.c
@@ -575,8 +575,8 @@ void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, rcti *rect)
ui_draw_tria_rect(&itemrect, 'h');
else
ui_draw_tria_rect(&itemrect, 'v');
-
-
+
+ (void)ofsx;
}
/************************** panel alignment *************************/
diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c
index 62043f240e4..9e7717260e6 100644
--- a/source/blender/editors/interface/interface_regions.c
+++ b/source/blender/editors/interface/interface_regions.c
@@ -484,6 +484,17 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but)
}
}
}
+ else if (ELEM(but->type, MENU, PULLDOWN)) {
+ if ((U.flag & USER_TOOLTIPS_PYTHON) == 0) {
+ if(but->menu_create_func && WM_menutype_contains((MenuType *)but->poin)) {
+ MenuType *mt= (MenuType *)but->poin;
+ BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), "Python: %s", mt->idname);
+ data->color[data->totline]= 0x888888;
+ data->totline++;
+ }
+ }
+
+ }
assert(data->totline < MAX_TOOLTIP_LINES);
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index 3c29369c6ac..cadcf959ace 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -2224,7 +2224,7 @@ void uiTemplateList(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *
/* create list items */
RNA_PROP_BEGIN(ptr, itemptr, prop) {
/* create button */
- if(i == 9)
+ if(!(i % 9))
row= uiLayoutRow(col, 0);
icon= list_item_icon_get(C, &itemptr, rnaicon, 1);
@@ -2239,7 +2239,6 @@ void uiTemplateList(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *
}
else if(listtype == 'c') {
/* compact layout */
- found= 0;
row= uiLayoutRow(layout, 1);
diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c
index 3f825762d74..0c755180b3a 100644
--- a/source/blender/editors/interface/resources.c
+++ b/source/blender/editors/interface/resources.c
@@ -1,6 +1,3 @@
-/** \file blender/editors/interface/resources.c
- * \ingroup edinterface
- */
/*
* $Id$
*
@@ -33,6 +30,10 @@
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
+/** \file blender/editors/interface/resources.c
+ * \ingroup edinterface
+ */
+
#include <math.h>
#include <stdlib.h>
#include <string.h>
@@ -1115,10 +1116,11 @@ void init_userdef_do_versions(void)
}
if(U.pad_rot_angle==0)
U.pad_rot_angle= 15;
-
- if(U.flag & USER_CUSTOM_RANGE)
- vDM_ColorBand_store(&U.coba_weight); /* signal for derivedmesh to use colorband */
-
+
+ /* signal for derivedmesh to use colorband */
+ /* run incase this was on and is now off in the user prefs [#28096] */
+ vDM_ColorBand_store((U.flag & USER_CUSTOM_RANGE) ? (&U.coba_weight):NULL);
+
if (bmain->versionfile <= 191) {
strcpy(U.plugtexdir, U.textudir);
strcpy(U.sounddir, "/");
@@ -1583,6 +1585,12 @@ void init_userdef_do_versions(void)
if (U.anisotropic_filter <= 0)
U.anisotropic_filter = 1;
+ if (U.ndof_sensitivity == 0.0f) {
+ U.ndof_sensitivity = 1.0f;
+ U.ndof_flag = NDOF_LOCK_HORIZON |
+ NDOF_SHOULD_PAN | NDOF_SHOULD_ZOOM | NDOF_SHOULD_ROTATE;
+ }
+
/* funny name, but it is GE stuff, moves userdef stuff to engine */
// XXX space_set_commmandline_options();
/* this timer uses U */
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index 7ca172c6945..f5f97c6a5f6 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -806,14 +806,14 @@ static int object_delete_exec(bContext *C, wmOperator *UNUSED(op))
{
Main *bmain= CTX_data_main(C);
Scene *scene= CTX_data_scene(C);
- int islamp= 0;
+ /* int islamp= 0; */ /* UNUSED */
if(CTX_data_edit_object(C))
return OPERATOR_CANCELLED;
CTX_DATA_BEGIN(C, Base*, base, selected_bases) {
- if(base->object->type==OB_LAMP) islamp= 1;
+ /* if(base->object->type==OB_LAMP) islamp= 1; */
/* deselect object -- it could be used in other scenes */
base->object->flag &= ~SELECT;
diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c
index f21241b6e7a..0fb7cf8b640 100644
--- a/source/blender/editors/object/object_relations.c
+++ b/source/blender/editors/object/object_relations.c
@@ -1096,7 +1096,7 @@ static int move_to_layer_exec(bContext *C, wmOperator *op)
Scene *scene= CTX_data_scene(C);
View3D *v3d= CTX_wm_view3d(C);
unsigned int lay, local;
- int islamp= 0;
+ /* int islamp= 0; */ /* UNUSED */
lay= move_to_layer_init(C, op);
lay &= 0xFFFFFF;
@@ -1112,7 +1112,7 @@ static int move_to_layer_exec(bContext *C, wmOperator *op)
base->object->lay= lay;
base->object->flag &= ~SELECT;
base->flag &= ~SELECT;
- if(base->object->type==OB_LAMP) islamp= 1;
+ /* if(base->object->type==OB_LAMP) islamp= 1; */
}
CTX_DATA_END;
}
@@ -1124,7 +1124,7 @@ static int move_to_layer_exec(bContext *C, wmOperator *op)
local= base->lay & 0xFF000000;
base->lay= lay + local;
base->object->lay= lay;
- if(base->object->type==OB_LAMP) islamp= 1;
+ /* if(base->object->type==OB_LAMP) islamp= 1; */
}
CTX_DATA_END;
}
diff --git a/source/blender/editors/screen/glutil.c b/source/blender/editors/screen/glutil.c
index 2918c98c84a..f56ae17d366 100644
--- a/source/blender/editors/screen/glutil.c
+++ b/source/blender/editors/screen/glutil.c
@@ -92,6 +92,44 @@ GLubyte stipple_quarttone[128] = {
136,136,136,136,0,0,0,0,34,34,34,34,0,0,0,0};
+GLubyte stipple_diag_stripes_pos[128] = {
+ 0x00, 0xff, 0x00, 0xff, 0x01, 0xfe, 0x01, 0xfe,
+ 0x03, 0xfc, 0x03, 0xfc, 0x07, 0xf8, 0x07, 0xf8,
+ 0x0f, 0xf0, 0x0f, 0xf0, 0x1f, 0xe0, 0x1f, 0xe0,
+ 0x3f, 0xc0, 0x3f, 0xc0, 0x7f, 0x80, 0x7f, 0x80,
+ 0xff, 0x00, 0xff, 0x00, 0xfe, 0x01, 0xfe, 0x01,
+ 0xfc, 0x03, 0xfc, 0x03, 0xf8, 0x07, 0xf8, 0x07,
+ 0xf0, 0x0f, 0xf0, 0x0f, 0xe0, 0x1f, 0xe0, 0x1f,
+ 0xc0, 0x3f, 0xc0, 0x3f, 0x80, 0x7f, 0x80, 0x7f,
+ 0x00, 0xff, 0x00, 0xff, 0x01, 0xfe, 0x01, 0xfe,
+ 0x03, 0xfc, 0x03, 0xfc, 0x07, 0xf8, 0x07, 0xf8,
+ 0x0f, 0xf0, 0x0f, 0xf0, 0x1f, 0xe0, 0x1f, 0xe0,
+ 0x3f, 0xc0, 0x3f, 0xc0, 0x7f, 0x80, 0x7f, 0x80,
+ 0xff, 0x00, 0xff, 0x00, 0xfe, 0x01, 0xfe, 0x01,
+ 0xfc, 0x03, 0xfc, 0x03, 0xf8, 0x07, 0xf8, 0x07,
+ 0xf0, 0x0f, 0xf0, 0x0f, 0xe0, 0x1f, 0xe0, 0x1f,
+ 0xc0, 0x3f, 0xc0, 0x3f, 0x80, 0x7f, 0x80, 0x7f};
+
+
+GLubyte stipple_diag_stripes_neg[128] = {
+ 0xff, 0x00, 0xff, 0x00, 0xfe, 0x01, 0xfe, 0x01,
+ 0xfc, 0x03, 0xfc, 0x03, 0xf8, 0x07, 0xf8, 0x07,
+ 0xf0, 0x0f, 0xf0, 0x0f, 0xe0, 0x1f, 0xe0, 0x1f,
+ 0xc0, 0x3f, 0xc0, 0x3f, 0x80, 0x7f, 0x80, 0x7f,
+ 0x00, 0xff, 0x00, 0xff, 0x01, 0xfe, 0x01, 0xfe,
+ 0x03, 0xfc, 0x03, 0xfc, 0x07, 0xf8, 0x07, 0xf8,
+ 0x0f, 0xf0, 0x0f, 0xf0, 0x1f, 0xe0, 0x1f, 0xe0,
+ 0x3f, 0xc0, 0x3f, 0xc0, 0x7f, 0x80, 0x7f, 0x80,
+ 0xff, 0x00, 0xff, 0x00, 0xfe, 0x01, 0xfe, 0x01,
+ 0xfc, 0x03, 0xfc, 0x03, 0xf8, 0x07, 0xf8, 0x07,
+ 0xf0, 0x0f, 0xf0, 0x0f, 0xe0, 0x1f, 0xe0, 0x1f,
+ 0xc0, 0x3f, 0xc0, 0x3f, 0x80, 0x7f, 0x80, 0x7f,
+ 0x00, 0xff, 0x00, 0xff, 0x01, 0xfe, 0x01, 0xfe,
+ 0x03, 0xfc, 0x03, 0xfc, 0x07, 0xf8, 0x07, 0xf8,
+ 0x0f, 0xf0, 0x0f, 0xf0, 0x1f, 0xe0, 0x1f, 0xe0,
+ 0x3f, 0xc0, 0x3f, 0xc0, 0x7f, 0x80, 0x7f, 0x80};
+
+
void fdrawbezier(float vec[4][3])
{
float dist;
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index 68326edfb11..1410331700f 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -301,7 +301,7 @@ int ED_operator_object_active_editable(bContext *C)
int ED_operator_object_active_editable_mesh(bContext *C)
{
Object *ob = ED_object_active_context(C);
- return ((ob != NULL) && !(ob->id.lib) && !(ob->restrictflag & OB_RESTRICT_VIEW) && ob->type == OB_MESH);
+ return ((ob != NULL) && !(ob->id.lib) && !(ob->restrictflag & OB_RESTRICT_VIEW) && ob->type == OB_MESH && !(((ID *)ob->data)->lib));
}
int ED_operator_object_active_editable_font(bContext *C)
diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c
index c9a6aa87cd0..32004fd4525 100644
--- a/source/blender/editors/sculpt_paint/paint_image.c
+++ b/source/blender/editors/sculpt_paint/paint_image.c
@@ -2187,7 +2187,7 @@ static int IsectPoly2Df_twoside(const float pt[2], float uv[][2], const int tot)
/* One of the most important function for projectiopn painting, since it selects the pixels to be added into each bucket.
* initialize pixels from this face where it intersects with the bucket_index, optionally initialize pixels for removing seams */
-static void project_paint_face_init(const ProjPaintState *ps, const int thread_index, const int bucket_index, const int face_index, const int image_index, rctf *bucket_bounds, const ImBuf *ibuf)
+static void project_paint_face_init(const ProjPaintState *ps, const int thread_index, const int bucket_index, const int face_index, const int image_index, rctf *bucket_bounds, const ImBuf *ibuf, const short clamp_u, const short clamp_v)
{
/* Projection vars, to get the 3D locations into screen space */
MemArena *arena = ps->arena_mt[thread_index];
@@ -2304,14 +2304,24 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i
if (pixel_bounds_array(uv_clip, &bounds_px, ibuf->x, ibuf->y, uv_clip_tot)) {
-
+
+ if(clamp_u) {
+ CLAMP(bounds_px.xmin, 0, ibuf->x);
+ CLAMP(bounds_px.xmax, 0, ibuf->x);
+ }
+
+ if(clamp_v) {
+ CLAMP(bounds_px.ymin, 0, ibuf->y);
+ CLAMP(bounds_px.ymax, 0, ibuf->y);
+ }
+
/* clip face and */
has_isect = 0;
for (y = bounds_px.ymin; y < bounds_px.ymax; y++) {
//uv[1] = (((float)y) + 0.5f) / (float)ibuf->y;
uv[1] = (float)y / ibuf_yf; /* use pixel offset UV coords instead */
-
+
has_x_isect = 0;
for (x = bounds_px.xmin; x < bounds_px.xmax; x++) {
//uv[0] = (((float)x) + 0.5f) / ibuf->x;
@@ -2630,6 +2640,7 @@ static void project_bucket_init(const ProjPaintState *ps, const int thread_index
LinkNode *node;
int face_index, image_index=0;
ImBuf *ibuf = NULL;
+ Image *ima = NULL;
MTFace *tf;
Image *tpage_last = NULL;
@@ -2638,9 +2649,10 @@ static void project_bucket_init(const ProjPaintState *ps, const int thread_index
if (ps->image_tot==1) {
/* Simple loop, no context switching */
ibuf = ps->projImages[0].ibuf;
-
+ ima = ps->projImages[0].ima;
+
for (node = ps->bucketFaces[bucket_index]; node; node= node->next) {
- project_paint_face_init(ps, thread_index, bucket_index, GET_INT_FROM_POINTER(node->link), 0, bucket_bounds, ibuf);
+ project_paint_face_init(ps, thread_index, bucket_index, GET_INT_FROM_POINTER(node->link), 0, bucket_bounds, ibuf, ima->tpageflag & IMA_CLAMP_U, ima->tpageflag & IMA_CLAMP_V);
}
}
else {
@@ -2659,14 +2671,14 @@ static void project_bucket_init(const ProjPaintState *ps, const int thread_index
for (image_index=0; image_index < ps->image_tot; image_index++) {
if (ps->projImages[image_index].ima == tpage_last) {
ibuf = ps->projImages[image_index].ibuf;
+ ima = ps->projImages[image_index].ima;
break;
}
}
}
/* context switching done */
- project_paint_face_init(ps, thread_index, bucket_index, face_index, image_index, bucket_bounds, ibuf);
-
+ project_paint_face_init(ps, thread_index, bucket_index, face_index, image_index, bucket_bounds, ibuf, ima->tpageflag & IMA_CLAMP_U, ima->tpageflag & IMA_CLAMP_V);
}
}
diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c
index 7ddf5dff000..09873566d4a 100644
--- a/source/blender/editors/sculpt_paint/paint_stroke.c
+++ b/source/blender/editors/sculpt_paint/paint_stroke.c
@@ -832,6 +832,13 @@ int paint_stroke_modal(bContext *C, wmOperator *op, wmEvent *event)
float mouse[2];
int first= 0;
+ // let NDOF motion pass through to the 3D view so we can paint and rotate simultaneously!
+ // this isn't perfect... even when an extra MOUSEMOVE is spoofed, the stroke discards it
+ // since the 2D deltas are zero -- code in this file needs to be updated to use the
+ // post-NDOF_MOTION MOUSEMOVE
+ if (event->type == NDOF_MOTION)
+ return OPERATOR_PASS_THROUGH;
+
if(!stroke->stroke_started) {
stroke->last_mouse_position[0] = event->x;
stroke->last_mouse_position[1] = event->y;
diff --git a/source/blender/editors/space_image/image_intern.h b/source/blender/editors/space_image/image_intern.h
index e9e77ddf430..399157da85c 100644
--- a/source/blender/editors/space_image/image_intern.h
+++ b/source/blender/editors/space_image/image_intern.h
@@ -73,6 +73,7 @@ void IMAGE_OT_view_zoom(struct wmOperatorType *ot);
void IMAGE_OT_view_zoom_in(struct wmOperatorType *ot);
void IMAGE_OT_view_zoom_out(struct wmOperatorType *ot);
void IMAGE_OT_view_zoom_ratio(struct wmOperatorType *ot);
+void IMAGE_OT_view_ndof(struct wmOperatorType *ot);
void IMAGE_OT_new(struct wmOperatorType *ot);
void IMAGE_OT_open(struct wmOperatorType *ot);
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index d5515bd1cf8..e0ebde589a8 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -437,6 +437,56 @@ void IMAGE_OT_view_zoom(wmOperatorType *ot)
"Factor", "Zoom factor, values higher than 1.0 zoom in, lower values zoom out.", -FLT_MAX, FLT_MAX);
}
+/********************** NDOF operator *********************/
+
+/* Combined pan/zoom from a 3D mouse device.
+ * Z zooms, XY pans
+ * "view" (not "paper") control -- user moves the viewpoint, not the image being viewed
+ * that explains the negative signs in the code below
+ */
+
+static int view_ndof_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
+{
+ SpaceImage *sima= CTX_wm_space_image(C);
+ ARegion *ar= CTX_wm_region(C);
+
+ wmNDOFMotionData* ndof = (wmNDOFMotionData*) event->customdata;
+
+ float dt = ndof->dt;
+ /* tune these until it feels right */
+ const float zoom_sensitivity = 0.5f; // 50% per second (I think)
+ const float pan_sensitivity = 300.f; // screen pixels per second
+
+ float pan_x = pan_sensitivity * dt * ndof->tvec[0] / sima->zoom;
+ float pan_y = pan_sensitivity * dt * ndof->tvec[1] / sima->zoom;
+
+ /* "mouse zoom" factor = 1 + (dx + dy) / 300
+ * what about "ndof zoom" factor? should behave like this:
+ * at rest -> factor = 1
+ * move forward -> factor > 1
+ * move backward -> factor < 1
+ */
+ float zoom_factor = 1.f + zoom_sensitivity * dt * -ndof->tvec[2];
+
+ sima_zoom_set_factor(sima, ar, zoom_factor);
+ sima->xof += pan_x;
+ sima->yof += pan_y;
+
+ ED_region_tag_redraw(ar);
+
+ return OPERATOR_FINISHED;
+}
+
+void IMAGE_OT_view_ndof(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "NDOF Pan/Zoom";
+ ot->idname= "IMAGE_OT_view_ndof";
+
+ /* api callbacks */
+ ot->invoke= view_ndof_invoke;
+}
+
/********************** view all operator *********************/
/* Updates the fields of the View2D member of the SpaceImage struct.
diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c
index 2e9544f5d20..afab4ede229 100644
--- a/source/blender/editors/space_image/space_image.c
+++ b/source/blender/editors/space_image/space_image.c
@@ -469,6 +469,7 @@ static void image_operatortypes(void)
WM_operatortype_append(IMAGE_OT_view_zoom_in);
WM_operatortype_append(IMAGE_OT_view_zoom_out);
WM_operatortype_append(IMAGE_OT_view_zoom_ratio);
+ WM_operatortype_append(IMAGE_OT_view_ndof);
WM_operatortype_append(IMAGE_OT_new);
WM_operatortype_append(IMAGE_OT_open);
@@ -518,6 +519,9 @@ static void image_keymap(struct wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "IMAGE_OT_view_pan", MIDDLEMOUSE, KM_PRESS, KM_SHIFT, 0);
WM_keymap_add_item(keymap, "IMAGE_OT_view_pan", MOUSEPAN, 0, 0, 0);
+ WM_keymap_add_item(keymap, "IMAGE_OT_view_all", NDOF_BUTTON_FIT, KM_PRESS, 0, 0); // or view selected?
+ WM_keymap_add_item(keymap, "IMAGE_OT_view_ndof", NDOF_MOTION, 0, 0, 0);
+
WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_in", WHEELINMOUSE, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_out", WHEELOUTMOUSE, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "IMAGE_OT_view_zoom_in", PADPLUSKEY, KM_PRESS, 0, 0);
diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c
index cd1fa5c16a7..950b3c72fe7 100644
--- a/source/blender/editors/space_node/node_draw.c
+++ b/source/blender/editors/space_node/node_draw.c
@@ -781,14 +781,15 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
iconbutw, UI_UNIT_Y, NULL, 0.0, 0.0, 1.0, 0.5, "");
}
{ /* always hide/reveal unused sockets */
- int shade;
-
- iconofs-=iconbutw;
// XXX re-enable
- /*if(node_has_hidden_sockets(node))
+ /* int shade;
+ if(node_has_hidden_sockets(node))
shade= -40;
- else*/
- shade= -90;
+ else
+ shade= -90; */
+
+ iconofs-=iconbutw;
+
uiDefIconBut(node->block, LABEL, B_REDR, ICON_PLUS, iconofs, rct->ymax-NODE_DY,
iconbutw, UI_UNIT_Y, NULL, 0.0, 0.0, 1.0, 0.5, "");
}
diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c
index 4230a43d2ec..c719f749582 100644
--- a/source/blender/editors/space_node/node_edit.c
+++ b/source/blender/editors/space_node/node_edit.c
@@ -1101,7 +1101,7 @@ void NODE_OT_backimage_move(wmOperatorType *ot)
ot->cancel= snode_bg_viewmove_cancel;
/* flags */
- ot->flag= OPTYPE_BLOCKING;
+ ot->flag= OPTYPE_BLOCKING|OPTYPE_GRAB_POINTER;
}
static int backimage_zoom(bContext *C, wmOperator *op)
@@ -2216,6 +2216,12 @@ static int node_link_modal(bContext *C, wmOperator *op, wmEvent *event)
/* we might need to remove a link */
if(in_out==SOCK_OUT)
node_remove_extra_links(snode, link->tosock, link);
+
+ /* when linking to group outputs, update the socket type */
+ /* XXX this should all be part of a generic update system */
+ if (!link->tonode) {
+ link->tosock->type = link->fromsock->type;
+ }
}
else if (outside_group_rect(snode) && (link->tonode || link->fromnode)) {
/* automatically add new group socket */
diff --git a/source/blender/editors/space_sequencer/sequencer_add.c b/source/blender/editors/space_sequencer/sequencer_add.c
index f6e3dc3dd0a..b105b2507ab 100644
--- a/source/blender/editors/space_sequencer/sequencer_add.c
+++ b/source/blender/editors/space_sequencer/sequencer_add.c
@@ -101,6 +101,8 @@ static void sequencer_generic_props__internal(wmOperatorType *ot, int flag)
RNA_def_boolean(ot->srna, "replace_sel", 1, "Replace Selection", "replace the current selection");
+ RNA_def_boolean(ot->srna, "overlap", 0, "Allow Overlap", "Don't correct overlap on new sequence strips");
+
if(flag & SEQPROP_FILES)
RNA_def_collection_runtime(ot->srna, "files", &RNA_OperatorFileListElement, "Files", "");
}
@@ -250,7 +252,11 @@ static int sequencer_add_scene_strip_exec(bContext *C, wmOperator *op)
seq_active_set(scene, seq);
seq->flag |= SELECT;
}
-
+
+ if(RNA_boolean_get(op->ptr, "overlap") == FALSE) {
+ if(seq_test_overlap(ed->seqbasep, seq)) shuffle_seq(ed->seqbasep, seq, scene);
+ }
+
WM_event_add_notifier(C, NC_SCENE|ND_SEQUENCER, scene);
return OPERATOR_FINISHED;
@@ -305,6 +311,7 @@ static int sequencer_add_generic_strip_exec(bContext *C, wmOperator *op, SeqLoad
SeqLoadInfo seq_load;
Sequence *seq;
int tot_files;
+ const short overlap= RNA_boolean_get(op->ptr, "overlap");
seq_load_operator_info(&seq_load, op);
@@ -325,12 +332,20 @@ static int sequencer_add_generic_strip_exec(bContext *C, wmOperator *op, SeqLoad
BLI_join_dirfile(seq_load.path, sizeof(seq_load.path), dir_only, file_only);
seq= seq_load_func(C, ed->seqbasep, &seq_load);
+
+ if(overlap == FALSE) {
+ if(seq_test_overlap(ed->seqbasep, seq)) shuffle_seq(ed->seqbasep, seq, scene);
+ }
}
RNA_END;
}
else {
/* single file */
seq= seq_load_func(C, ed->seqbasep, &seq_load);
+
+ if(overlap == FALSE) {
+ if(seq_test_overlap(ed->seqbasep, seq)) shuffle_seq(ed->seqbasep, seq, scene);
+ }
}
if (seq_load.tot_success==0) {
@@ -506,7 +521,11 @@ static int sequencer_add_image_strip_exec(bContext *C, wmOperator *op)
/* last active name */
strncpy(ed->act_imagedir, strip->dir, FILE_MAXDIR-1);
-
+
+ if(RNA_boolean_get(op->ptr, "overlap") == FALSE) {
+ if(seq_test_overlap(ed->seqbasep, seq)) shuffle_seq(ed->seqbasep, seq, scene);
+ }
+
WM_event_add_notifier(C, NC_SCENE|ND_SEQUENCER, scene);
return OPERATOR_FINISHED;
@@ -656,7 +675,9 @@ static int sequencer_add_effect_strip_exec(bContext *C, wmOperator *op)
}
}
- if(seq_test_overlap(ed->seqbasep, seq)) shuffle_seq(ed->seqbasep, seq, scene);
+ if(RNA_boolean_get(op->ptr, "overlap") == FALSE) {
+ if(seq_test_overlap(ed->seqbasep, seq)) shuffle_seq(ed->seqbasep, seq, scene);
+ }
update_changed_seq_and_deps(scene, seq, 1, 1); /* runs calc_sequence */
diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c
index 594d2942e8f..98687bb90e0 100644
--- a/source/blender/editors/space_sequencer/sequencer_draw.c
+++ b/source/blender/editors/space_sequencer/sequencer_draw.c
@@ -639,6 +639,25 @@ static void draw_seq_strip(Scene *scene, ARegion *ar, Sequence *seq, int outline
/* draw sound wave */
if(seq->type == SEQ_SOUND) drawseqwave(scene, seq, x1, y1, x2, y2, (ar->v2d.cur.xmax - ar->v2d.cur.xmin)/ar->winx);
+ /* draw lock */
+ if(seq->flag & SEQ_LOCK) {
+ glEnable(GL_POLYGON_STIPPLE);
+ glEnable(GL_BLEND);
+
+ /* light stripes */
+ glColor4ub(255, 255, 255, 32);
+ glPolygonStipple(stipple_diag_stripes_pos);
+ glRectf(x1, y1, x2, y2);
+
+ /* dark stripes */
+ glColor4ub(0, 0, 0, 32);
+ glPolygonStipple(stipple_diag_stripes_neg);
+ glRectf(x1, y1, x2, y2);
+
+ glDisable(GL_POLYGON_STIPPLE);
+ glDisable(GL_BLEND);
+ }
+
get_seq_color3ubv(scene, seq, col);
if (G.moving && (seq->flag & SELECT)) {
if(seq->flag & SEQ_OVERLAP) {
diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c
index 2bd6bd624df..13eb24ed1f2 100644
--- a/source/blender/editors/space_text/text_ops.c
+++ b/source/blender/editors/space_text/text_ops.c
@@ -36,6 +36,7 @@
#include <string.h>
#include <ctype.h> /* ispunct */
#include <sys/stat.h>
+#include <errno.h>
#include "MEM_guardedalloc.h"
@@ -449,15 +450,14 @@ static void txt_write_file(Text *text, ReportList *reports)
FILE *fp;
TextLine *tmp;
struct stat st;
- int res;
- char file[FILE_MAXDIR+FILE_MAXFILE];
+ char filepath[FILE_MAXDIR+FILE_MAXFILE];
- BLI_strncpy(file, text->name, FILE_MAXDIR+FILE_MAXFILE);
- BLI_path_abs(file, G.main->name);
+ BLI_strncpy(filepath, text->name, FILE_MAXDIR+FILE_MAXFILE);
+ BLI_path_abs(filepath, G.main->name);
- fp= fopen(file, "w");
+ fp= fopen(filepath, "w");
if(fp==NULL) {
- BKE_report(reports, RPT_ERROR, "Unable to save file.");
+ BKE_reportf(reports, RPT_ERROR, "Unable to save \"%s\": %s.", filepath, errno ? strerror(errno) : "Unknown error writing file");
return;
}
@@ -471,8 +471,13 @@ static void txt_write_file(Text *text, ReportList *reports)
fclose (fp);
- res= stat(file, &st);
- text->mtime= st.st_mtime;
+ if(stat(filepath, &st) == 0) {
+ text->mtime= st.st_mtime;
+ }
+ else {
+ text->mtime= 0;
+ BKE_reportf(reports, RPT_WARNING, "Unable to stat \"%s\": %s.", filepath, errno ? strerror(errno) : "Unknown error starrng file");
+ }
if(text->flags & TXT_ISDIRTY)
text->flags ^= TXT_ISDIRTY;
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index d2ff6eef097..6e3f6549ba3 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -675,6 +675,104 @@ static void draw_view_axis(RegionView3D *rv3d)
glDisable(GL_BLEND);
}
+/* draw center and axis of rotation for ongoing 3D mouse navigation */
+static void draw_rotation_guide(RegionView3D *rv3d)
+{
+ float o[3]; // center of rotation
+ float end[3]; // endpoints for drawing
+
+ float color[4] = {0.f ,0.4235f, 1.f, 1.f}; // bright blue so it matches device LEDs
+
+ negate_v3_v3(o, rv3d->ofs);
+
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glShadeModel(GL_SMOOTH);
+ glPointSize(5);
+ glEnable(GL_POINT_SMOOTH);
+ glDepthMask(0); // don't overwrite zbuf
+
+ if (rv3d->rot_angle != 0.f) {
+ // -- draw rotation axis --
+ float scaled_axis[3];
+ const float scale = rv3d->dist;
+ mul_v3_v3fl(scaled_axis, rv3d->rot_axis, scale);
+
+ glBegin(GL_LINE_STRIP);
+ color[3] = 0.f; // more transparent toward the ends
+ glColor4fv(color);
+ add_v3_v3v3(end, o, scaled_axis);
+ glVertex3fv(end);
+
+ // color[3] = 0.2f + fabsf(rv3d->rot_angle); // modulate opacity with angle
+ // ^^ neat idea, but angle is frame-rate dependent, so it's usually close to 0.2
+
+ color[3] = 0.5f; // more opaque toward the center
+ glColor4fv(color);
+ glVertex3fv(o);
+
+ color[3] = 0.f;
+ glColor4fv(color);
+ sub_v3_v3v3(end, o, scaled_axis);
+ glVertex3fv(end);
+ glEnd();
+
+ // -- draw ring around rotation center --
+ {
+ #define ROT_AXIS_DETAIL 13
+ const float s = 0.05f * scale;
+ const float step = 2.f * M_PI / ROT_AXIS_DETAIL;
+ float angle;
+ int i;
+
+ float q[4]; // rotate ring so it's perpendicular to axis
+ const int upright = fabsf(rv3d->rot_axis[2]) >= 0.95f;
+ if (!upright)
+ {
+ const float up[3] = {0.f, 0.f, 1.f};
+ float vis_angle, vis_axis[3];
+
+ cross_v3_v3v3(vis_axis, up, rv3d->rot_axis);
+ vis_angle = acosf(dot_v3v3(up, rv3d->rot_axis));
+ axis_angle_to_quat(q, vis_axis, vis_angle);
+ }
+
+ color[3] = 0.25f; // somewhat faint
+ glColor4fv(color);
+ glBegin(GL_LINE_LOOP);
+ for (i = 0, angle = 0.f; i < ROT_AXIS_DETAIL; ++i, angle += step)
+ {
+ float p[3] = { s * cosf(angle), s * sinf(angle), 0.f };
+
+ if (!upright)
+ mul_qt_v3(q, p);
+
+ add_v3_v3(p, o);
+ glVertex3fv(p);
+ }
+ glEnd();
+ }
+
+ color[3] = 1.f; // solid dot
+ }
+ else
+ color[3] = 0.5f; // see-through dot
+
+ // -- draw rotation center --
+ glColor4fv(color);
+ glBegin(GL_POINTS);
+ glVertex3fv(o);
+ glEnd();
+
+ // find screen coordinates for rotation center, then draw pretty icon
+ // mul_m4_v3(rv3d->persinv, rot_center);
+ // UI_icon_draw(rot_center[0], rot_center[1], ICON_NDOF_TURN);
+ // ^^ just playing around, does not work
+
+ glDisable(GL_BLEND);
+ glDisable(GL_POINT_SMOOTH);
+ glDepthMask(1);
+}
static void draw_view_icon(RegionView3D *rv3d)
{
@@ -2618,6 +2716,10 @@ void view3d_main_area_draw(const bContext *C, ARegion *ar)
BDR_drawSketch(C);
}
+ if ((U.ndof_flag & NDOF_SHOW_GUIDE) && (rv3d->viewlock != RV3D_LOCKED) && (rv3d->persp != RV3D_CAMOB))
+ // TODO: draw something else (but not this) during fly mode
+ draw_rotation_guide(rv3d);
+
ED_region_pixelspace(ar);
// retopo_paint_view_update(v3d);
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index 9ff73767b4c..e6fd9e8867b 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -129,7 +129,6 @@ void ED_view3d_camera_lock_sync(View3D *v3d, RegionView3D *rv3d)
}
else {
ED_view3d_to_object(v3d->camera, rv3d->ofs, rv3d->viewquat, rv3d->dist);
- root_parent= v3d->camera;
DAG_id_tag_update(&v3d->camera->id, OB_RECALC_OB);
WM_main_add_notifier(NC_OBJECT|ND_TRANSFORM, v3d->camera);
}
@@ -929,6 +928,244 @@ void VIEW3D_OT_rotate(wmOperatorType *ot)
ot->flag= OPTYPE_BLOCKING|OPTYPE_GRAB_POINTER;
}
+// NDOF utility functions
+// (should these functions live in this file?)
+float ndof_to_axis_angle(struct wmNDOFMotionData* ndof, float axis[3])
+{
+ return ndof->dt * normalize_v3_v3(axis, ndof->rvec);
+}
+
+void ndof_to_quat(struct wmNDOFMotionData* ndof, float q[4])
+{
+ float axis[3];
+ float angle;
+
+ angle= ndof_to_axis_angle(ndof, axis);
+ axis_angle_to_quat(q, axis, angle);
+}
+
+static int ndof_orbit_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
+// -- "orbit" navigation (trackball/turntable)
+// -- zooming
+// -- panning in rotationally-locked views
+{
+ RegionView3D* rv3d = CTX_wm_region_view3d(C);
+ wmNDOFMotionData* ndof = (wmNDOFMotionData*) event->customdata;
+
+ rv3d->rot_angle = 0.f; // off by default, until changed later this function
+
+ if (ndof->progress != P_FINISHING) {
+ const float dt = ndof->dt;
+
+ // tune these until everything feels right
+ const float rot_sensitivity = 1.f;
+ const float zoom_sensitivity = 1.f;
+ const float pan_sensitivity = 1.f;
+
+ // rather have bool, but...
+ int has_rotation = rv3d->viewlock != RV3D_LOCKED && !is_zero_v3(ndof->rvec);
+
+ float view_inv[4];
+ invert_qt_qt(view_inv, rv3d->viewquat);
+
+ //#define DEBUG_NDOF_MOTION
+ #ifdef DEBUG_NDOF_MOTION
+ printf("ndof: T=(%.2f,%.2f,%.2f) R=(%.2f,%.2f,%.2f) dt=%.3f delivered to 3D view\n",
+ ndof->tx, ndof->ty, ndof->tz, ndof->rx, ndof->ry, ndof->rz, ndof->dt);
+ #endif
+
+ if (ndof->tvec[2]) {
+ // Zoom!
+ // velocity should be proportional to the linear velocity attained by rotational motion of same strength
+ // [got that?]
+ // proportional to arclength = radius * angle
+
+ float zoom_distance = zoom_sensitivity * rv3d->dist * dt * ndof->tvec[2];
+ rv3d->dist += zoom_distance;
+ }
+
+ if (rv3d->viewlock == RV3D_LOCKED) {
+ /* rotation not allowed -- explore panning options instead */
+ float pan_vec[3] = {ndof->tvec[0], ndof->tvec[1], 0.0f};
+ mul_v3_fl(pan_vec, pan_sensitivity * rv3d->dist * dt);
+
+ /* transform motion from view to world coordinates */
+ invert_qt_qt(view_inv, rv3d->viewquat);
+ mul_qt_v3(view_inv, pan_vec);
+
+ /* move center of view opposite of hand motion (this is camera mode, not object mode) */
+ sub_v3_v3(rv3d->ofs, pan_vec);
+ }
+
+ if (has_rotation) {
+
+ const int invert = U.ndof_flag & NDOF_ORBIT_INVERT_AXES;
+
+ rv3d->view = RV3D_VIEW_USER;
+
+ if (U.flag & USER_TRACKBALL) {
+ float rot[4];
+ #if 0 // -------------------------- Mike's nifty original version
+ float view_inv_conj[4];
+
+ ndof_to_quat(ndof, rot);
+ // mul_qt_fl(rot, rot_sensitivity);
+ // ^^ no apparent effect
+
+ if (invert)
+ invert_qt(rot);
+
+ copy_qt_qt(view_inv_conj, view_inv);
+ conjugate_qt(view_inv_conj);
+
+ // transform rotation from view to world coordinates
+ mul_qt_qtqt(rot, view_inv, rot);
+ mul_qt_qtqt(rot, rot, view_inv_conj);
+ #else // ---------------------------------------- Mike's revised version
+ float axis[3];
+ float angle = rot_sensitivity * ndof_to_axis_angle(ndof, axis);
+
+ if (invert)
+ angle = -angle;
+
+ // transform rotation axis from view to world coordinates
+ mul_qt_v3(view_inv, axis);
+
+ // update the onscreen doo-dad
+ rv3d->rot_angle = angle;
+ copy_v3_v3(rv3d->rot_axis, axis);
+
+ axis_angle_to_quat(rot, axis, angle);
+ #endif // --------------------------------------------
+ // apply rotation
+ mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rot);
+ } else {
+ /* turntable view code by John Aughey, adapted for 3D mouse by [mce] */
+ float angle, rot[4];
+ float xvec[3] = {1,0,0};
+
+ /* Determine the direction of the x vector (for rotating up and down) */
+ mul_qt_v3(view_inv, xvec);
+
+ /* Perform the up/down rotation */
+ angle = rot_sensitivity * dt * ndof->rvec[0];
+ if (invert)
+ angle = -angle;
+ rot[0] = cos(angle);
+ mul_v3_v3fl(rot+1, xvec, sin(angle));
+ mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rot);
+
+ /* Perform the orbital rotation */
+ angle = rot_sensitivity * dt * ndof->rvec[1];
+ if (invert)
+ angle = -angle;
+
+ // update the onscreen doo-dad
+ rv3d->rot_angle = angle;
+ rv3d->rot_axis[0] = 0;
+ rv3d->rot_axis[1] = 0;
+ rv3d->rot_axis[2] = 1;
+
+ rot[0] = cos(angle);
+ rot[1] = rot[2] = 0.0;
+ rot[3] = sin(angle);
+ mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rot);
+ }
+ }
+ }
+
+ ED_region_tag_redraw(CTX_wm_region(C));
+
+ return OPERATOR_FINISHED;
+}
+
+void VIEW3D_OT_ndof_orbit(struct wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "NDOF Orbit View";
+ ot->description = "Explore every angle of an object using the 3D mouse.";
+ ot->idname = "VIEW3D_OT_ndof_orbit";
+
+ /* api callbacks */
+ ot->invoke = ndof_orbit_invoke;
+ ot->poll = ED_operator_view3d_active;
+
+ /* flags */
+ ot->flag = 0;
+}
+
+static int ndof_pan_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
+// -- "pan" navigation
+// -- zoom or dolly?
+{
+ RegionView3D* rv3d = CTX_wm_region_view3d(C);
+ wmNDOFMotionData* ndof = (wmNDOFMotionData*) event->customdata;
+
+ rv3d->rot_angle = 0.f; // we're panning here! so erase any leftover rotation from other operators
+
+ if (ndof->progress != P_FINISHING) {
+ const float dt = ndof->dt;
+ float view_inv[4];
+#if 0 // ------------------------------------------- zoom with Z
+ // tune these until everything feels right
+ const float zoom_sensitivity = 1.f;
+ const float pan_sensitivity = 1.f;
+
+ float pan_vec[3] = {
+ ndof->tx, ndof->ty, 0
+ };
+
+ // "zoom in" or "translate"? depends on zoom mode in user settings?
+ if (ndof->tz) {
+ float zoom_distance = zoom_sensitivity * rv3d->dist * dt * ndof->tz;
+ rv3d->dist += zoom_distance;
+ }
+
+ mul_v3_fl(pan_vec, pan_sensitivity * rv3d->dist * dt);
+#else // ------------------------------------------------------- dolly with Z
+ float speed = 10.f; // blender units per second
+ // ^^ this is ok for default cube scene, but should scale with.. something
+
+ // tune these until everything feels right
+ const float forward_sensitivity = 1.f;
+ const float vertical_sensitivity = 0.4f;
+ const float lateral_sensitivity = 0.6f;
+
+ float pan_vec[3] = {lateral_sensitivity * ndof->tvec[0],
+ vertical_sensitivity * ndof->tvec[1],
+ forward_sensitivity * ndof->tvec[2]
+ };
+
+ mul_v3_fl(pan_vec, speed * dt);
+#endif
+ /* transform motion from view to world coordinates */
+ invert_qt_qt(view_inv, rv3d->viewquat);
+ mul_qt_v3(view_inv, pan_vec);
+
+ /* move center of view opposite of hand motion (this is camera mode, not object mode) */
+ sub_v3_v3(rv3d->ofs, pan_vec);
+ }
+
+ ED_region_tag_redraw(CTX_wm_region(C));
+
+ return OPERATOR_FINISHED;
+}
+
+void VIEW3D_OT_ndof_pan(struct wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "NDOF Pan View";
+ ot->description = "Position your viewpoint with the 3D mouse.";
+ ot->idname = "VIEW3D_OT_ndof_pan";
+
+ /* api callbacks */
+ ot->invoke = ndof_pan_invoke;
+ ot->poll = ED_operator_view3d_active;
+
+ /* flags */
+ ot->flag = 0;
+}
+
/* ************************ viewmove ******************************** */
@@ -3196,398 +3433,6 @@ int ED_view3d_autodist_depth_seg(struct ARegion *ar, const int mval_sta[2], cons
return (*depth==FLT_MAX) ? 0:1;
}
-/* ********************* NDOF ************************ */
-/* note: this code is confusing and unclear... (ton) */
-/* **************************************************** */
-
-// ndof scaling will be moved to user setting.
-// In the mean time this is just a place holder.
-
-// Note: scaling in the plugin and ghostwinlay.c
-// should be removed. With driver default setting,
-// each axis returns approx. +-200 max deflection.
-
-// The values I selected are based on the older
-// polling i/f. With event i/f, the sensistivity
-// can be increased for improved response from
-// small deflections of the device input.
-
-
-// lukep notes : i disagree on the range.
-// the normal 3Dconnection driver give +/-400
-// on defaut range in other applications
-// and up to +/- 1000 if set to maximum
-// because i remove the scaling by delta,
-// which was a bad idea as it depend of the system
-// speed and os, i changed the scaling values, but
-// those are still not ok
-
-#if 0
-static float ndof_axis_scale[6] = {
- +0.01, // Tx
- +0.01, // Tz
- +0.01, // Ty
- +0.0015, // Rx
- +0.0015, // Rz
- +0.0015 // Ry
-};
-
-static void filterNDOFvalues(float *sbval)
-{
- int i=0;
- float max = 0.0;
-
- for (i =0; i<6;i++)
- if (fabs(sbval[i]) > max)
- max = fabs(sbval[i]);
- for (i =0; i<6;i++)
- if (fabs(sbval[i]) != max )
- sbval[i]=0.0;
-}
-
-// statics for controlling rv3d->dist corrections.
-// viewmoveNDOF zeros and adjusts rv3d->ofs.
-// viewmove restores based on dz_flag state.
-
-int dz_flag = 0;
-float m_dist;
-
-void viewmoveNDOFfly(ARegion *ar, View3D *v3d, int UNUSED(mode))
-{
- RegionView3D *rv3d= ar->regiondata;
- int i;
- float phi;
- float dval[7];
- // static fval[6] for low pass filter; device input vector is dval[6]
- static float fval[6];
- float tvec[3],rvec[3];
- float q1[4];
- float mat[3][3];
- float upvec[3];
-
-
- /*----------------------------------------------------
- * sometimes this routine is called from headerbuttons
- * viewmove needs to refresh the screen
- */
-// XXX areawinset(ar->win);
-
-
- // fetch the current state of the ndof device
-// XXX getndof(dval);
-
- if (v3d->ndoffilter)
- filterNDOFvalues(fval);
-
- // Scale input values
-
-// if(dval[6] == 0) return; // guard against divide by zero
-
- for(i=0;i<6;i++) {
-
- // user scaling
- dval[i] = dval[i] * ndof_axis_scale[i];
- }
-
-
- // low pass filter with zero crossing reset
-
- for(i=0;i<6;i++) {
- if((dval[i] * fval[i]) >= 0)
- dval[i] = (fval[i] * 15 + dval[i]) / 16;
- else
- fval[i] = 0;
- }
-
-
- // force perspective mode. This is a hack and is
- // incomplete. It doesn't actually effect the view
- // until the first draw and doesn't update the menu
- // to reflect persp mode.
-
- rv3d->persp = RV3D_PERSP;
-
-
- // Correct the distance jump if rv3d->dist != 0
-
- // This is due to a side effect of the original
- // mouse view rotation code. The rotation point is
- // set a distance in front of the viewport to
- // make rotating with the mouse look better.
- // The distance effect is written at a low level
- // in the view management instead of the mouse
- // view function. This means that all other view
- // movement devices must subtract this from their
- // view transformations.
-
- if(rv3d->dist != 0.0) {
- dz_flag = 1;
- m_dist = rv3d->dist;
- upvec[0] = upvec[1] = 0;
- upvec[2] = rv3d->dist;
- copy_m3_m4(mat, rv3d->viewinv);
- mul_m3_v3(mat, upvec);
- sub_v3_v3(rv3d->ofs, upvec);
- rv3d->dist = 0.0;
- }
-
-
- // Apply rotation
- // Rotations feel relatively faster than translations only in fly mode, so
- // we have no choice but to fix that here (not in the plugins)
- rvec[0] = -0.5 * dval[3];
- rvec[1] = -0.5 * dval[4];
- rvec[2] = -0.5 * dval[5];
-
- // rotate device x and y by view z
-
- copy_m3_m4(mat, rv3d->viewinv);
- mat[2][2] = 0.0f;
- mul_m3_v3(mat, rvec);
-
- // rotate the view
-
- phi = normalize_v3(rvec);
- if(phi != 0) {
- axis_angle_to_quat(q1,rvec,phi);
- mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, q1);
- }
-
-
- // Apply translation
-
- tvec[0] = dval[0];
- tvec[1] = dval[1];
- tvec[2] = -dval[2];
-
- // the next three lines rotate the x and y translation coordinates
- // by the current z axis angle
-
- copy_m3_m4(mat, rv3d->viewinv);
- mat[2][2] = 0.0f;
- mul_m3_v3(mat, tvec);
-
- // translate the view
-
- sub_v3_v3(rv3d->ofs, tvec);
-
-
- /*----------------------------------------------------
- * refresh the screen XXX
- */
-
- // update render preview window
-
-// XXX BIF_view3d_previewrender_signal(ar, PR_DBASE|PR_DISPRECT);
-}
-
-void viewmoveNDOF(Scene *scene, ARegion *ar, View3D *v3d, int UNUSED(mode))
-{
- RegionView3D *rv3d= ar->regiondata;
- float fval[7];
- float dvec[3];
- float sbadjust = 1.0f;
- float len;
- short use_sel = 0;
- Object *ob = OBACT;
- float m[3][3];
- float m_inv[3][3];
- float xvec[3] = {1,0,0};
- float yvec[3] = {0,-1,0};
- float zvec[3] = {0,0,1};
- float phi;
- float q1[4];
- float obofs[3];
- float reverse;
- //float diff[4];
- float d, curareaX, curareaY;
- float mat[3][3];
- float upvec[3];
-
- /* Sensitivity will control how fast the view rotates. The value was
- * obtained experimentally by tweaking until the author didn't get dizzy watching.
- * Perhaps this should be a configurable user parameter.
- */
- float psens = 0.005f * (float) U.ndof_pan; /* pan sensitivity */
- float rsens = 0.005f * (float) U.ndof_rotate; /* rotate sensitivity */
- float zsens = 0.3f; /* zoom sensitivity */
-
- const float minZoom = -30.0f;
- const float maxZoom = 300.0f;
-
- //reset view type
- rv3d->view = 0;
-//printf("passing here \n");
-//
- if (scene->obedit==NULL && ob && !(ob->mode & OB_MODE_POSE)) {
- use_sel = 1;
- }
-
- if((dz_flag)||rv3d->dist==0) {
- dz_flag = 0;
- rv3d->dist = m_dist;
- upvec[0] = upvec[1] = 0;
- upvec[2] = rv3d->dist;
- copy_m3_m4(mat, rv3d->viewinv);
- mul_m3_v3(mat, upvec);
- add_v3_v3(rv3d->ofs, upvec);
- }
-
- /*----------------------------------------------------
- * sometimes this routine is called from headerbuttons
- * viewmove needs to refresh the screen
- */
-// XXX areawinset(curarea->win);
-
- /*----------------------------------------------------
- * record how much time has passed. clamp at 10 Hz
- * pretend the previous frame occurred at the clamped time
- */
-// now = PIL_check_seconds_timer();
- // frametime = (now - prevTime);
- // if (frametime > 0.1f){ /* if more than 1/10s */
- // frametime = 1.0f/60.0; /* clamp at 1/60s so no jumps when starting to move */
-// }
-// prevTime = now;
- // sbadjust *= 60 * frametime; /* normalize ndof device adjustments to 100Hz for framerate independence */
-
- /* fetch the current state of the ndof device & enforce dominant mode if selected */
-// XXX getndof(fval);
- if (v3d->ndoffilter)
- filterNDOFvalues(fval);
-
-
- // put scaling back here, was previously in ghostwinlay
- fval[0] = fval[0] * (1.0f/600.0f);
- fval[1] = fval[1] * (1.0f/600.0f);
- fval[2] = fval[2] * (1.0f/1100.0f);
- fval[3] = fval[3] * 0.00005f;
- fval[4] =-fval[4] * 0.00005f;
- fval[5] = fval[5] * 0.00005f;
- fval[6] = fval[6] / 1000000.0f;
-
- // scale more if not in perspective mode
- if (rv3d->persp == RV3D_ORTHO) {
- fval[0] = fval[0] * 0.05f;
- fval[1] = fval[1] * 0.05f;
- fval[2] = fval[2] * 0.05f;
- fval[3] = fval[3] * 0.9f;
- fval[4] = fval[4] * 0.9f;
- fval[5] = fval[5] * 0.9f;
- zsens *= 8;
- }
-
- /* set object offset */
- if (ob) {
- obofs[0] = -ob->obmat[3][0];
- obofs[1] = -ob->obmat[3][1];
- obofs[2] = -ob->obmat[3][2];
- }
- else {
- copy_v3_v3(obofs, rv3d->ofs);
- }
-
- /* calc an adjustment based on distance from camera
- disabled per patch 14402 */
- d = 1.0f;
-
-/* if (ob) {
- sub_v3_v3v3(diff, obofs, rv3d->ofs);
- d = len_v3(diff);
- }
-*/
-
- reverse = (rv3d->persmat[2][1] < 0.0f) ? -1.0f : 1.0f;
-
- /*----------------------------------------------------
- * ndof device pan
- */
- psens *= 1.0f + d;
- curareaX = sbadjust * psens * fval[0];
- curareaY = sbadjust * psens * fval[1];
- dvec[0] = curareaX * rv3d->persinv[0][0] + curareaY * rv3d->persinv[1][0];
- dvec[1] = curareaX * rv3d->persinv[0][1] + curareaY * rv3d->persinv[1][1];
- dvec[2] = curareaX * rv3d->persinv[0][2] + curareaY * rv3d->persinv[1][2];
- add_v3_v3(rv3d->ofs, dvec);
-
- /*----------------------------------------------------
- * ndof device dolly
- */
- len = zsens * sbadjust * fval[2];
-
- if (rv3d->persp==RV3D_CAMOB) {
- if(rv3d->persp==RV3D_CAMOB) { /* This is stupid, please fix - TODO */
- rv3d->camzoom+= 10.0f * -len;
- }
- if (rv3d->camzoom < minZoom) rv3d->camzoom = minZoom;
- else if (rv3d->camzoom > maxZoom) rv3d->camzoom = maxZoom;
- }
- else if ((rv3d->dist> 0.001*v3d->grid) && (rv3d->dist<10.0*v3d->far)) {
- rv3d->dist*=(1.0 + len);
- }
-
-
- /*----------------------------------------------------
- * ndof device turntable
- * derived from the turntable code in viewmove
- */
-
- /* Get the 3x3 matrix and its inverse from the quaternion */
- quat_to_mat3( m,rv3d->viewquat);
- invert_m3_m3(m_inv,m);
-
- /* Determine the direction of the x vector (for rotating up and down) */
- /* This can likely be compuated directly from the quaternion. */
- mul_m3_v3(m_inv,xvec);
- mul_m3_v3(m_inv,yvec);
- mul_m3_v3(m_inv,zvec);
-
- /* Perform the up/down rotation */
- phi = sbadjust * rsens * /*0.5f * */ fval[3]; /* spin vertically half as fast as horizontally */
- q1[0] = cos(phi);
- mul_v3_v3fl(q1+1, xvec, sin(phi));
- mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, q1);
-
- if (use_sel) {
- conjugate_qt(q1); /* conj == inv for unit quat */
- sub_v3_v3(rv3d->ofs, obofs);
- mul_qt_v3(q1, rv3d->ofs);
- add_v3_v3(rv3d->ofs, obofs);
- }
-
- /* Perform the orbital rotation */
- /* Perform the orbital rotation
- If the seen Up axis is parallel to the zoom axis, rotation should be
- achieved with a pure Roll motion (no Spin) on the device. When you start
- to tilt, moving from Top to Side view, Spinning will increasingly become
- more relevant while the Roll component will decrease. When a full
- Side view is reached, rotations around the world's Up axis are achieved
- with a pure Spin-only motion. In other words the control of the spinning
- around the world's Up axis should move from the device's Spin axis to the
- device's Roll axis depending on the orientation of the world's Up axis
- relative to the screen. */
- //phi = sbadjust * rsens * reverse * fval[4]; /* spin the knob, y axis */
- phi = sbadjust * rsens * (yvec[2] * fval[4] + zvec[2] * fval[5]);
- q1[0] = cos(phi);
- q1[1] = q1[2] = 0.0;
- q1[3] = sin(phi);
- mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, q1);
-
- if (use_sel) {
- conjugate_qt(q1);
- sub_v3_v3(rv3d->ofs, obofs);
- mul_qt_v3(q1, rv3d->ofs);
- add_v3_v3(rv3d->ofs, obofs);
- }
-
- /*----------------------------------------------------
- * refresh the screen
- */
-// XXX scrarea_do_windraw(curarea);
-}
-#endif // if 0, unused NDof code
-
-
/* Gets the view trasnformation from a camera
* currently dosnt take camzoom into account
*
diff --git a/source/blender/editors/space_view3d/view3d_fly.c b/source/blender/editors/space_view3d/view3d_fly.c
index ed1ed5b3881..046037a092f 100644
--- a/source/blender/editors/space_view3d/view3d_fly.c
+++ b/source/blender/editors/space_view3d/view3d_fly.c
@@ -29,6 +29,9 @@
/* defines VIEW3D_OT_fly modal operator */
+//#define NDOF_FLY_DEBUG
+//#define NDOF_FLY_DRAW_TOOMUCH // is this needed for ndof? - commented so redraw doesnt thrash - campbell
+
#include "DNA_anim_types.h"
#include "DNA_scene_types.h"
#include "DNA_object_types.h"
@@ -106,7 +109,7 @@ void fly_modal_keymap(wmKeyConfig *keyconf)
wmKeyMap *keymap= WM_modalkeymap_get(keyconf, "View3D Fly Modal");
/* this function is called for each spacetype, only needs to add map once */
- if(keymap) return;
+ if (keymap) return;
keymap= WM_modalkeymap_add(keyconf, "View3D Fly Modal", modal_items);
@@ -143,7 +146,6 @@ void fly_modal_keymap(wmKeyConfig *keyconf)
/* assign map to operators */
WM_modalkeymap_assign(keymap, "VIEW3D_OT_fly");
-
}
typedef struct FlyInfo {
@@ -158,7 +160,9 @@ typedef struct FlyInfo {
short state;
short use_precision;
short redraw;
- int mval[2];
+
+ int mval[2]; /* latest 2D mouse values */
+ wmNDOFMotionData* ndof; /* latest 3D mouse values */
/* fly state state */
float speed; /* the speed the view is moving per redraw */
@@ -257,17 +261,21 @@ static int initFlyInfo (bContext *C, FlyInfo *fly, wmOperator *op, wmEvent *even
fly->ar = CTX_wm_region(C);
fly->scene= CTX_data_scene(C);
- if(fly->rv3d->persp==RV3D_CAMOB && fly->v3d->camera->id.lib) {
+#ifdef NDOF_FLY_DEBUG
+ puts("\n-- fly begin --");
+#endif
+
+ if (fly->rv3d->persp==RV3D_CAMOB && fly->v3d->camera->id.lib) {
BKE_report(op->reports, RPT_ERROR, "Cannot fly a camera from an external library");
return FALSE;
}
- if(fly->v3d->ob_centre) {
+ if (fly->v3d->ob_centre) {
BKE_report(op->reports, RPT_ERROR, "Cannot fly when the view is locked to an object");
return FALSE;
}
- if(fly->rv3d->persp==RV3D_CAMOB && fly->v3d->camera->constraints.first) {
+ if (fly->rv3d->persp==RV3D_CAMOB && fly->v3d->camera->constraints.first) {
BKE_report(op->reports, RPT_ERROR, "Cannot fly an object with constraints");
return FALSE;
}
@@ -283,11 +291,15 @@ static int initFlyInfo (bContext *C, FlyInfo *fly, wmOperator *op, wmEvent *even
fly->grid= 1.0f;
fly->use_precision= 0;
+#ifdef NDOF_FLY_DRAW_TOOMUCH
+ fly->redraw= 1;
+#endif
fly->dvec_prev[0]= fly->dvec_prev[1]= fly->dvec_prev[2]= 0.0f;
fly->timer= WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER, 0.01f);
VECCOPY2D(fly->mval, event->mval)
+ fly->ndof = NULL;
fly->time_lastdraw= fly->time_lastwheel= PIL_check_seconds_timer();
@@ -307,7 +319,7 @@ static int initFlyInfo (bContext *C, FlyInfo *fly, wmOperator *op, wmEvent *even
fly->dist_backup= fly->rv3d->dist;
if (fly->rv3d->persp==RV3D_CAMOB) {
Object *ob_back;
- if((U.uiflag & USER_CAM_LOCK_NO_PARENT)==0 && (fly->root_parent=fly->v3d->camera->parent)) {
+ if ((U.uiflag & USER_CAM_LOCK_NO_PARENT)==0 && (fly->root_parent=fly->v3d->camera->parent)) {
while(fly->root_parent->parent)
fly->root_parent= fly->root_parent->parent;
ob_back= fly->root_parent;
@@ -325,12 +337,22 @@ static int initFlyInfo (bContext *C, FlyInfo *fly, wmOperator *op, wmEvent *even
negate_v3_v3(fly->rv3d->ofs, fly->v3d->camera->obmat[3]);
fly->rv3d->dist=0.0;
- } else {
+ }
+ else {
/* perspective or ortho */
if (fly->rv3d->persp==RV3D_ORTHO)
fly->rv3d->persp= RV3D_PERSP; /*if ortho projection, make perspective */
+
copy_qt_qt(fly->rot_backup, fly->rv3d->viewquat);
copy_v3_v3(fly->ofs_backup, fly->rv3d->ofs);
+
+ /* the dist defines a vector that is infront of the offset
+ to rotate the view about.
+ this is no good for fly mode because we
+ want to rotate about the viewers center.
+ but to correct the dist removal we must
+ alter offset so the view doesn't jump. */
+
fly->rv3d->dist= 0.0f;
upvec[2]= fly->dist_backup; /*x and y are 0*/
@@ -338,7 +360,6 @@ static int initFlyInfo (bContext *C, FlyInfo *fly, wmOperator *op, wmEvent *even
sub_v3_v3(fly->rv3d->ofs, upvec);
/*Done with correcting for the dist*/
}
-
/* center the mouse, probably the UI mafia are against this but without its quite annoying */
WM_cursor_warp(CTX_wm_window(C), fly->ar->winrct.xmin + fly->ar->winx/2, fly->ar->winrct.ymin + fly->ar->winy/2);
@@ -353,9 +374,13 @@ static int flyEnd(bContext *C, FlyInfo *fly)
float upvec[3];
- if(fly->state == FLY_RUNNING)
+ if (fly->state == FLY_RUNNING)
return OPERATOR_RUNNING_MODAL;
+#ifdef NDOF_FLY_DEBUG
+ puts("\n-- fly end --");
+#endif
+
WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), fly->timer);
ED_region_draw_cb_exit(fly->ar->type, fly->draw_handle_pixel);
@@ -366,14 +391,14 @@ static int flyEnd(bContext *C, FlyInfo *fly)
/* Revert to original view? */
if (fly->persp_backup==RV3D_CAMOB) { /* a camera view */
Object *ob_back;
- if(fly->root_parent)ob_back= fly->root_parent;
- else ob_back= fly->v3d->camera;
+ ob_back= (fly->root_parent) ? fly->root_parent : fly->v3d->camera;
/* store the original camera loc and rot */
object_tfm_restore(ob_back, fly->obtfm);
DAG_id_tag_update(&ob_back->id, OB_RECALC_OB);
- } else {
+ }
+ else {
/* Non Camera we need to reset the view back to the original location bacause the user canceled*/
copy_qt_qt(rv3d->viewquat, fly->rot_backup);
copy_v3_v3(rv3d->ofs, fly->ofs_backup);
@@ -398,10 +423,13 @@ static int flyEnd(bContext *C, FlyInfo *fly)
rv3d->rflag &= ~RV3D_NAVIGATING;
//XXX2.5 BIF_view3d_previewrender_signal(fly->sa, PR_DBASE|PR_DISPRECT); /* not working at the moment not sure why */
- if(fly->obtfm)
+ if (fly->obtfm)
MEM_freeN(fly->obtfm);
- if(fly->state == FLY_CONFIRM) {
+ if (fly->ndof)
+ MEM_freeN(fly->ndof);
+
+ if (fly->state == FLY_CONFIRM) {
MEM_freeN(fly);
return OPERATOR_FINISHED;
}
@@ -417,7 +445,52 @@ static void flyEvent(FlyInfo *fly, wmEvent *event)
}
else if (event->type == MOUSEMOVE) {
VECCOPY2D(fly->mval, event->mval);
- } /* handle modal keymap first */
+ }
+ else if (event->type == NDOF_MOTION) {
+ // do these automagically get delivered? yes.
+ // puts("ndof motion detected in fly mode!");
+ // static const char* tag_name = "3D mouse position";
+
+ wmNDOFMotionData* incoming_ndof = (wmNDOFMotionData*) event->customdata;
+ switch (incoming_ndof->progress) {
+ case P_STARTING:
+ // start keeping track of 3D mouse position
+#ifdef NDOF_FLY_DEBUG
+ puts("start keeping track of 3D mouse position");
+#endif
+ // fall through...
+ case P_IN_PROGRESS:
+ // update 3D mouse position
+#ifdef NDOF_FLY_DEBUG
+ putchar('.'); fflush(stdout);
+#endif
+ if (fly->ndof == NULL) {
+ // fly->ndof = MEM_mallocN(sizeof(wmNDOFMotionData), tag_name);
+ fly->ndof = MEM_dupallocN(incoming_ndof);
+ // fly->ndof = malloc(sizeof(wmNDOFMotionData));
+ }
+ else {
+ memcpy(fly->ndof, incoming_ndof, sizeof(wmNDOFMotionData));
+ }
+ break;
+ case P_FINISHING:
+ // stop keeping track of 3D mouse position
+#ifdef NDOF_FLY_DEBUG
+ puts("stop keeping track of 3D mouse position");
+#endif
+ if (fly->ndof) {
+ MEM_freeN(fly->ndof);
+ // free(fly->ndof);
+ fly->ndof = NULL;
+ }
+ /* update the time else the view will jump when 2D mouse/timer resume */
+ fly->time_lastdraw= PIL_check_seconds_timer();
+ break;
+ default:
+ ; // should always be one of the above 3
+ }
+ }
+ /* handle modal keymap first */
else if (event->type == EVT_MODAL_MAP) {
switch (event->val) {
case FLY_MODAL_CANCEL:
@@ -439,7 +512,9 @@ static void flyEvent(FlyInfo *fly, wmEvent *event)
/*Mouse wheel delays range from 0.5==slow to 0.01==fast*/
time_wheel = 1.0f + (10.0f - (20.0f * MIN2(time_wheel, 0.5f))); /* 0-0.5 -> 0-5.0 */
- if (fly->speed<0.0f) fly->speed= 0.0f;
+ if (fly->speed < 0.0f) {
+ fly->speed= 0.0f;
+ }
else {
if (event->shift)
fly->speed += fly->grid*time_wheel * 0.1f;
@@ -458,7 +533,9 @@ static void flyEvent(FlyInfo *fly, wmEvent *event)
fly->time_lastwheel = time_currwheel;
time_wheel = 1.0f + (10.0f - (20.0f * MIN2(time_wheel, 0.5f))); /* 0-0.5 -> 0-5.0 */
- if (fly->speed>0) fly->speed=0;
+ if (fly->speed > 0.0f) {
+ fly->speed=0;
+ }
else {
if (event->shift)
fly->speed-= fly->grid*time_wheel * 0.1f;
@@ -528,14 +605,81 @@ static void flyEvent(FlyInfo *fly, wmEvent *event)
case FLY_MODAL_PRECISION_DISABLE:
fly->use_precision= FALSE;
break;
+ }
+ }
+}
+
+static void move_camera(bContext* C, RegionView3D* rv3d, FlyInfo* fly, int orientationChanged, int positionChanged)
+{
+ /* we are in camera view so apply the view ofs and quat to the view matrix and set the camera to the view */
+
+ View3D* v3d = fly->v3d;
+ Scene *scene= fly->scene;
+ ID *id_key;
+
+ /* transform the parent or the camera? */
+ if (fly->root_parent) {
+ Object *ob_update;
+
+ float view_mat[4][4];
+ float prev_view_mat[4][4];
+ float prev_view_imat[4][4];
+ float diff_mat[4][4];
+ float parent_mat[4][4];
+
+ ED_view3d_to_m4(prev_view_mat, fly->rv3d->ofs, fly->rv3d->viewquat, fly->rv3d->dist);
+ invert_m4_m4(prev_view_imat, prev_view_mat);
+ ED_view3d_to_m4(view_mat, rv3d->ofs, rv3d->viewquat, rv3d->dist);
+ mul_m4_m4m4(diff_mat, prev_view_imat, view_mat);
+ mul_m4_m4m4(parent_mat, fly->root_parent->obmat, diff_mat);
+ object_apply_mat4(fly->root_parent, parent_mat, TRUE, FALSE);
+
+ // where_is_object(scene, fly->root_parent);
+
+ ob_update= v3d->camera->parent;
+ while(ob_update) {
+ DAG_id_tag_update(&ob_update->id, OB_RECALC_OB);
+ ob_update= ob_update->parent;
}
+
+ id_key= &fly->root_parent->id;
+ }
+ else {
+ float view_mat[4][4];
+ ED_view3d_to_m4(view_mat, rv3d->ofs, rv3d->viewquat, rv3d->dist);
+ object_apply_mat4(v3d->camera, view_mat, TRUE, FALSE);
+ id_key= &v3d->camera->id;
+ }
+
+ /* record the motion */
+ if (autokeyframe_cfra_can_key(scene, id_key)) {
+ ListBase dsources = {NULL, NULL};
+
+ /* add datasource override for the camera object */
+ ANIM_relative_keyingset_add_source(&dsources, id_key, NULL, NULL);
+
+ /* insert keyframes
+ * 1) on the first frame
+ * 2) on each subsequent frame
+ * TODO: need to check in future that frame changed before doing this
+ */
+ if (orientationChanged) {
+ KeyingSet *ks= ANIM_builtin_keyingset_get_named(NULL, "Rotation");
+ ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, (float)CFRA);
+ }
+ if (positionChanged) {
+ KeyingSet *ks= ANIM_builtin_keyingset_get_named(NULL, "Location");
+ ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, (float)CFRA);
+ }
+
+ /* free temp data */
+ BLI_freelistN(&dsources);
}
}
static int flyApply(bContext *C, FlyInfo *fly)
{
-
#define FLY_ROTATE_FAC 2.5f /* more is faster */
#define FLY_ZUP_CORRECT_FAC 0.1f /* amount to correct per step */
#define FLY_ZUP_CORRECT_ACCEL 0.05f /* increase upright momentum each step */
@@ -545,11 +689,7 @@ static int flyApply(bContext *C, FlyInfo *fly)
a fly loop where the user can move move the view as if they are flying
*/
RegionView3D *rv3d= fly->rv3d;
- View3D *v3d = fly->v3d;
ARegion *ar = fly->ar;
- Scene *scene= fly->scene;
-
- float prev_view_mat[4][4];
float mat[3][3], /* 3x3 copy of the view matrix so we can move allong the view axis */
dvec[3]={0,0,0}, /* this is the direction thast added to the view offset per redraw */
@@ -567,15 +707,11 @@ static int flyApply(bContext *C, FlyInfo *fly)
unsigned char
apply_rotation= 1; /* if the user presses shift they can look about without movinf the direction there looking*/
- if(fly->root_parent)
- ED_view3d_to_m4(prev_view_mat, fly->rv3d->ofs, fly->rv3d->viewquat, fly->rv3d->dist);
+#ifdef NDOF_FLY_DEBUG
+ static unsigned int iteration = 1;
+ printf("fly timer %d\n", iteration++);
+#endif
- /* the dist defines a vector that is infront of the offset
- to rotate the view about.
- this is no good for fly mode because we
- want to rotate about the viewers center.
- but to correct the dist removal we must
- alter offset so the view doesn't jump. */
xmargin= ar->winx/20.0f;
ymargin= ar->winy/20.0f;
@@ -605,23 +741,25 @@ static int flyApply(bContext *C, FlyInfo *fly)
*
* the mouse moves isnt linear */
- if(moffset[0]) {
+ if (moffset[0]) {
moffset[0] /= ar->winx - (xmargin*2);
moffset[0] *= fabsf(moffset[0]);
}
- if(moffset[1]) {
+ if (moffset[1]) {
moffset[1] /= ar->winy - (ymargin*2);
moffset[1] *= fabsf(moffset[1]);
}
/* Should we redraw? */
- if(fly->speed != 0.0f || moffset[0] || moffset[1] || fly->zlock || fly->xlock || dvec[0] || dvec[1] || dvec[2] ) {
+ if (fly->speed != 0.0f || moffset[0] || moffset[1] || fly->zlock || fly->xlock || dvec[0] || dvec[1] || dvec[2] ) {
float dvec_tmp[3];
double time_current; /*time how fast it takes for us to redraw, this is so simple scenes dont fly too fast */
float time_redraw;
float time_redraw_clamped;
-
+#ifdef NDOF_FLY_DRAW_TOOMUCH
+ fly->redraw= 1;
+#endif
time_current= PIL_check_seconds_timer();
time_redraw= (float)(time_current - fly->time_lastdraw);
time_redraw_clamped= MIN2(0.05f, time_redraw); /* clamt the redraw time to avoid jitter in roll correction */
@@ -648,8 +786,8 @@ static int flyApply(bContext *C, FlyInfo *fly)
mul_m3_v3(mat, dvec_tmp);
mul_v3_fl(dvec_tmp, time_redraw * 200.0f * fly->grid);
-
- } else {
+ }
+ else {
float roll; /* similar to the angle between the camera's up and the Z-up, but its very rough so just roll*/
/* rotate about the X axis- look up/down */
@@ -670,27 +808,28 @@ static int flyApply(bContext *C, FlyInfo *fly)
if (moffset[0]) {
/* if we're upside down invert the moffset */
- upvec[0]=0;
- upvec[1]=1;
- upvec[2]=0;
+ upvec[0]= 0.0f;
+ upvec[1]= 1.0f;
+ upvec[2]= 0.0f;
mul_m3_v3(mat, upvec);
- if(upvec[2] < 0.0f)
+ if (upvec[2] < 0.0f)
moffset[0]= -moffset[0];
/* make the lock vectors */
if (fly->zlock) {
- upvec[0]=0;
- upvec[1]=0;
- upvec[2]=1;
- } else {
- upvec[0]=0;
- upvec[1]=1;
- upvec[2]=0;
+ upvec[0]= 0.0f;
+ upvec[1]= 0.0f;
+ upvec[2]= 1.0f;
+ }
+ else {
+ upvec[0]= 0.0f;
+ upvec[1]= 1.0f;
+ upvec[2]= 0.0f;
mul_m3_v3(mat, upvec);
}
- axis_angle_to_quat( tmp_quat, upvec, (float)moffset[0] * time_redraw * FLY_ROTATE_FAC); /* Rotate about the relative up vec */
+ axis_angle_to_quat(tmp_quat, upvec, (float)moffset[0] * time_redraw * FLY_ROTATE_FAC); /* Rotate about the relative up vec */
mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, tmp_quat);
if (fly->xlock) fly->xlock = 2;/*check for rotation*/
@@ -698,25 +837,26 @@ static int flyApply(bContext *C, FlyInfo *fly)
}
if (fly->zlock==2) {
- upvec[0]=1;
- upvec[1]=0;
- upvec[2]=0;
+ upvec[0]= 1.0f;
+ upvec[1]= 0.0f;
+ upvec[2]= 0.0f;
mul_m3_v3(mat, upvec);
/*make sure we have some z rolling*/
if (fabsf(upvec[2]) > 0.00001f) {
- roll= upvec[2]*5;
- upvec[0]=0; /*rotate the view about this axis*/
- upvec[1]=0;
- upvec[2]=1;
+ roll= upvec[2] * 5.0f;
+ upvec[0]= 0.0f; /*rotate the view about this axis*/
+ upvec[1]= 0.0f;
+ upvec[2]= 1.0f;
mul_m3_v3(mat, upvec);
axis_angle_to_quat( tmp_quat, upvec, roll*time_redraw_clamped*fly->zlock_momentum * FLY_ZUP_CORRECT_FAC); /* Rotate about the relative up vec */
mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, tmp_quat);
fly->zlock_momentum += FLY_ZUP_CORRECT_ACCEL;
- } else {
- fly->zlock=1; /* dont check until the view rotates again */
+ }
+ else {
+ fly->zlock= 1; /* dont check until the view rotates again */
fly->zlock_momentum= 0.0f;
}
}
@@ -727,8 +867,8 @@ static int flyApply(bContext *C, FlyInfo *fly)
upvec[2]=1;
mul_m3_v3(mat, upvec);
/*make sure we have some z rolling*/
- if (fabs(upvec[2]) > 0.00001) {
- roll= upvec[2] * -5;
+ if (fabs(upvec[2]) > 0.00001f) {
+ roll= upvec[2] * -5.0f;
upvec[0]= 1.0f; /*rotate the view about this axis*/
upvec[1]= 0.0f;
@@ -740,7 +880,8 @@ static int flyApply(bContext *C, FlyInfo *fly)
mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, tmp_quat);
fly->xlock_momentum += 0.05f;
- } else {
+ }
+ else {
fly->xlock=1; /* see above */
fly->xlock_momentum= 0.0f;
}
@@ -784,96 +925,164 @@ static int flyApply(bContext *C, FlyInfo *fly)
ED_area_headerprint(fly->ar, "FlyKeys Speed:(+/- | Wheel), Upright Axis:X off/Z off, Slow:Shift, Direction:WASDRF, Ok:LMB, Pan:MMB, Cancel:RMB");
#endif
- /* we are in camera view so apply the view ofs and quat to the view matrix and set the camera to the view */
- if (rv3d->persp==RV3D_CAMOB) {
- ID *id_key;
- /* transform the parent or the camera? */
- if(fly->root_parent) {
- Object *ob_update;
-
- float view_mat[4][4];
- float prev_view_imat[4][4];
- float diff_mat[4][4];
- float parent_mat[4][4];
-
- invert_m4_m4(prev_view_imat, prev_view_mat);
- ED_view3d_to_m4(view_mat, rv3d->ofs, rv3d->viewquat, rv3d->dist);
- mul_m4_m4m4(diff_mat, prev_view_imat, view_mat);
- mul_m4_m4m4(parent_mat, fly->root_parent->obmat, diff_mat);
- object_apply_mat4(fly->root_parent, parent_mat, TRUE, FALSE);
-
- // where_is_object(scene, fly->root_parent);
-
- ob_update= v3d->camera->parent;
- while(ob_update) {
- DAG_id_tag_update(&ob_update->id, OB_RECALC_OB);
- ob_update= ob_update->parent;
- }
+ if (rv3d->persp==RV3D_CAMOB)
+ move_camera(C, rv3d, fly, (fly->xlock || fly->zlock || moffset[0] || moffset[1]), fly->speed);
- copy_m4_m4(prev_view_mat, view_mat);
+ }
+ else {
+ /* we're not redrawing but we need to update the time else the view will jump */
+ fly->time_lastdraw= PIL_check_seconds_timer();
+ }
+ /* end drawing */
+ copy_v3_v3(fly->dvec_prev, dvec);
+ }
- id_key= &fly->root_parent->id;
+ return OPERATOR_FINISHED;
+}
- }
- else {
- float view_mat[4][4];
- ED_view3d_to_m4(view_mat, rv3d->ofs, rv3d->viewquat, rv3d->dist);
- object_apply_mat4(v3d->camera, view_mat, TRUE, FALSE);
- id_key= &v3d->camera->id;
- }
+static int flyApply_ndof(bContext *C, FlyInfo *fly)
+{
+ /* shorthand for oft-used variables */
+ wmNDOFMotionData* ndof = fly->ndof;
+ const float dt = ndof->dt;
+ RegionView3D* rv3d = fly->rv3d;
+ const int flag = U.ndof_flag;
- /* record the motion */
- if (autokeyframe_cfra_can_key(scene, id_key)) {
- ListBase dsources = {NULL, NULL};
-
- /* add datasource override for the camera object */
- ANIM_relative_keyingset_add_source(&dsources, id_key, NULL, NULL);
-
- /* insert keyframes
- * 1) on the first frame
- * 2) on each subsequent frame
- * TODO: need to check in future that frame changed before doing this
- */
- if (fly->xlock || fly->zlock || moffset[0] || moffset[1]) {
- KeyingSet *ks= ANIM_builtin_keyingset_get_named(NULL, "Rotation");
- ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, (float)CFRA);
- }
- if (fly->speed) {
- KeyingSet *ks= ANIM_builtin_keyingset_get_named(NULL, "Location");
- ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, (float)CFRA);
- }
-
- /* free temp data */
- BLI_freelistN(&dsources);
- }
+/* int shouldRotate = (flag & NDOF_SHOULD_ROTATE) && (fly->pan_view == FALSE),
+ shouldTranslate = (flag & (NDOF_SHOULD_PAN | NDOF_SHOULD_ZOOM)); */
+
+ int shouldRotate = (fly->pan_view == FALSE),
+ shouldTranslate = TRUE;
+
+ float view_inv[4];
+ invert_qt_qt(view_inv, rv3d->viewquat);
+
+ rv3d->rot_angle = 0.f; // disable onscreen rotation doo-dad
+
+ if (shouldTranslate) {
+ const float forward_sensitivity = 1.f;
+ const float vertical_sensitivity = 0.4f;
+ const float lateral_sensitivity = 0.6f;
+
+ float speed = 10.f; /* blender units per second */
+ /* ^^ this is ok for default cube scene, but should scale with.. something */
+
+ float trans[3] = {
+ lateral_sensitivity * ndof->tvec[0],
+ vertical_sensitivity * ndof->tvec[1],
+ forward_sensitivity * ndof->tvec[2]
+ };
+
+ if (fly->use_precision)
+ speed *= 0.2f;
+
+ mul_v3_fl(trans, speed * dt);
+
+ // transform motion from view to world coordinates
+ mul_qt_v3(view_inv, trans);
+
+ if (flag & NDOF_FLY_HELICOPTER) {
+ /* replace world z component with device y (yes it makes sense) */
+ trans[2] = speed * dt * vertical_sensitivity * ndof->tvec[1];
+ }
+
+ if (rv3d->persp==RV3D_CAMOB) {
+ // respect camera position locks
+ Object *lock_ob= fly->root_parent ? fly->root_parent : fly->v3d->camera;
+ if (lock_ob->protectflag & OB_LOCK_LOCX) trans[0] = 0.f;
+ if (lock_ob->protectflag & OB_LOCK_LOCY) trans[1] = 0.f;
+ if (lock_ob->protectflag & OB_LOCK_LOCZ) trans[2] = 0.f;
+ }
+
+ if (!is_zero_v3(trans)) {
+ // move center of view opposite of hand motion (this is camera mode, not object mode)
+ sub_v3_v3(rv3d->ofs, trans);
+ shouldTranslate = TRUE;
+ }
+ else {
+ shouldTranslate = FALSE;
+ }
+ }
+
+ if (shouldRotate) {
+ const float turn_sensitivity = 1.f;
+
+ float rotation[4];
+ float axis[3];
+ float angle = turn_sensitivity * ndof_to_axis_angle(ndof, axis);
+
+ if (fabsf(angle) > 0.0001f) {
+ shouldRotate = TRUE;
+
+ if (fly->use_precision)
+ angle *= 0.2f;
+
+ /* transform rotation axis from view to world coordinates */
+ mul_qt_v3(view_inv, axis);
+
+ // apply rotation to view
+ axis_angle_to_quat(rotation, axis, angle);
+ mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rotation);
+
+ if (flag & NDOF_LOCK_HORIZON) {
+ /* force an upright viewpoint
+ * TODO: make this less... sudden */
+ float view_horizon[3] = {1.f, 0.f, 0.f}; /* view +x */
+ float view_direction[3] = {0.f, 0.f, -1.f}; /* view -z (into screen) */
+
+ /* find new inverse since viewquat has changed */
+ invert_qt_qt(view_inv, rv3d->viewquat);
+ /* could apply reverse rotation to existing view_inv to save a few cycles */
+
+ /* transform view vectors to world coordinates */
+ mul_qt_v3(view_inv, view_horizon);
+ mul_qt_v3(view_inv, view_direction);
+
+ /* find difference between view & world horizons
+ * true horizon lives in world xy plane, so look only at difference in z */
+ angle = -asinf(view_horizon[2]);
+
+#ifdef NDOF_FLY_DEBUG
+ printf("lock horizon: adjusting %.1f degrees\n\n", RAD2DEG(angle));
+#endif
+
+ /* rotate view so view horizon = world horizon */
+ axis_angle_to_quat(rotation, view_direction, angle);
+ mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rotation);
}
- } else
- /*were not redrawing but we need to update the time else the view will jump */
- fly->time_lastdraw= PIL_check_seconds_timer();
- /* end drawing */
- copy_v3_v3(fly->dvec_prev, dvec);
+
+ rv3d->view = RV3D_VIEW_USER;
+ }
+ else {
+ shouldRotate = FALSE;
+ }
}
-/* moved to flyEnd() */
+ if (shouldTranslate || shouldRotate) {
+ fly->redraw = TRUE;
+
+ if (rv3d->persp==RV3D_CAMOB) {
+ move_camera(C, rv3d, fly, shouldRotate, shouldTranslate);
+ }
+ }
return OPERATOR_FINISHED;
}
-
static int fly_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
RegionView3D *rv3d= CTX_wm_region_view3d(C);
FlyInfo *fly;
- if(rv3d->viewlock)
+ if (rv3d->viewlock)
return OPERATOR_CANCELLED;
fly= MEM_callocN(sizeof(FlyInfo), "FlyOperation");
op->customdata= fly;
- if(initFlyInfo(C, fly, op, event)==FALSE) {
+ if (initFlyInfo(C, fly, op, event)==FALSE) {
MEM_freeN(op->customdata);
return OPERATOR_CANCELLED;
}
@@ -908,21 +1117,28 @@ static int fly_modal(bContext *C, wmOperator *op, wmEvent *event)
flyEvent(fly, event);
- if(event->type==TIMER && event->customdata == fly->timer)
+ if (fly->ndof) { /* 3D mouse overrules [2D mouse + timer] */
+ if (event->type==NDOF_MOTION) {
+ flyApply_ndof(C, fly);
+ }
+ }
+ else if (event->type==TIMER && event->customdata == fly->timer) {
flyApply(C, fly);
+ }
do_draw |= fly->redraw;
exit_code = flyEnd(C, fly);
- if(exit_code!=OPERATOR_RUNNING_MODAL)
+ if (exit_code!=OPERATOR_RUNNING_MODAL)
do_draw= TRUE;
- if(do_draw) {
- if(rv3d->persp==RV3D_CAMOB) {
+ if (do_draw) {
+ if (rv3d->persp==RV3D_CAMOB) {
WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, fly_object);
}
+ // puts("redraw!"); // too frequent, commented with NDOF_FLY_DRAW_TOOMUCH for now
ED_region_tag_redraw(CTX_wm_region(C));
}
diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c
index ae80a554e08..5b95ae63e56 100644
--- a/source/blender/editors/space_view3d/view3d_header.c
+++ b/source/blender/editors/space_view3d/view3d_header.c
@@ -280,7 +280,8 @@ static char *view3d_modeselect_pup(Scene *scene)
str += sprintf(str, formatstr, "Object Mode", OB_MODE_OBJECT, ICON_OBJECT_DATA);
- if(ob==NULL) return string;
+ if(ob==NULL || ob->data==NULL) return string;
+ if(ob->id.lib || ((ID *)ob->data)->lib) return string;
/* if active object is editable */
if ( ((ob->type == OB_MESH)
diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h
index f965fbe6e32..8f322047283 100644
--- a/source/blender/editors/space_view3d/view3d_intern.h
+++ b/source/blender/editors/space_view3d/view3d_intern.h
@@ -51,6 +51,7 @@ struct ARegionType;
struct bPoseChannel;
struct bAnimVizSettings;
struct bMotionPath;
+struct wmNDOFMotionData;
#define BL_NEAR_CLIP 0.001
@@ -76,6 +77,8 @@ void VIEW3D_OT_dolly(struct wmOperatorType *ot);
void VIEW3D_OT_zoom_camera_1_to_1(struct wmOperatorType *ot);
void VIEW3D_OT_move(struct wmOperatorType *ot);
void VIEW3D_OT_rotate(struct wmOperatorType *ot);
+void VIEW3D_OT_ndof_orbit(struct wmOperatorType *ot);
+void VIEW3D_OT_ndof_pan(struct wmOperatorType *ot);
void VIEW3D_OT_view_all(struct wmOperatorType *ot);
void VIEW3D_OT_viewnumpad(struct wmOperatorType *ot);
void VIEW3D_OT_view_selected(struct wmOperatorType *ot);
@@ -95,6 +98,8 @@ void VIEW3D_OT_zoom_border(struct wmOperatorType *ot);
void VIEW3D_OT_drawtype(struct wmOperatorType *ot);
void view3d_boxview_copy(ScrArea *sa, ARegion *ar);
+void ndof_to_quat(struct wmNDOFMotionData* ndof, float q[4]);
+float ndof_to_axis_angle(struct wmNDOFMotionData* ndof, float axis[3]);
/* view3d_fly.c */
void view3d_keymap(struct wmKeyConfig *keyconf);
diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c
index 05ef79a9f29..e47cb1db753 100644
--- a/source/blender/editors/space_view3d/view3d_ops.c
+++ b/source/blender/editors/space_view3d/view3d_ops.c
@@ -64,6 +64,8 @@ void view3d_operatortypes(void)
WM_operatortype_append(VIEW3D_OT_zoom);
WM_operatortype_append(VIEW3D_OT_zoom_camera_1_to_1);
WM_operatortype_append(VIEW3D_OT_dolly);
+ WM_operatortype_append(VIEW3D_OT_ndof_orbit);
+ WM_operatortype_append(VIEW3D_OT_ndof_pan);
WM_operatortype_append(VIEW3D_OT_view_all);
WM_operatortype_append(VIEW3D_OT_viewnumpad);
WM_operatortype_append(VIEW3D_OT_view_orbit);
@@ -161,6 +163,17 @@ void view3d_keymap(wmKeyConfig *keyconf)
RNA_boolean_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_all", HOMEKEY, KM_PRESS, 0, 0)->ptr, "center", 0); /* only without camera view */
RNA_boolean_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_all", CKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "center", 1);
+ /* 3D mouse */
+ WM_keymap_add_item(keymap, "VIEW3D_OT_ndof_orbit", NDOF_MOTION, 0, 0, 0);
+ WM_keymap_add_item(keymap, "VIEW3D_OT_ndof_pan", NDOF_MOTION, 0, KM_SHIFT, 0);
+ WM_keymap_add_item(keymap, "VIEW3D_OT_view_selected", NDOF_BUTTON_FIT, KM_PRESS, 0, 0);
+ RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_FRONT, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_FRONT);
+ RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_BACK, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_BACK);
+ RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_LEFT, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_LEFT);
+ RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_RIGHT, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_RIGHT);
+ RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_TOP, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_TOP);
+ RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_BOTTOM, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_BOTTOM);
+
/* numpad view hotkeys*/
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", PAD0, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_CAMERA);
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", PAD1, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_FRONT);
@@ -210,6 +223,17 @@ void view3d_keymap(wmKeyConfig *keyconf)
RNA_enum_set(kmi->ptr, "type", RV3D_VIEW_BOTTOM);
RNA_boolean_set(kmi->ptr, "align_active", TRUE);
+ /* 3D mouse align */
+ kmi= WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_FRONT, KM_PRESS, KM_SHIFT, 0);
+ RNA_enum_set(kmi->ptr, "type", RV3D_VIEW_FRONT);
+ RNA_boolean_set(kmi->ptr, "align_active", TRUE);
+ kmi= WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_RIGHT, KM_PRESS, KM_SHIFT, 0);
+ RNA_enum_set(kmi->ptr, "type", RV3D_VIEW_RIGHT);
+ RNA_boolean_set(kmi->ptr, "align_active", TRUE);
+ kmi= WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_TOP, KM_PRESS, KM_SHIFT, 0);
+ RNA_enum_set(kmi->ptr, "type", RV3D_VIEW_TOP);
+ RNA_boolean_set(kmi->ptr, "align_active", TRUE);
+
WM_keymap_add_item(keymap, "VIEW3D_OT_localview", PADSLASHKEY, KM_PRESS, 0, 0);
/* layers, shift + alt are properties set in invoke() */
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index 9290e1fc631..c6835b0cad3 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -889,14 +889,14 @@ static unsigned int samplerect(unsigned int *buf, int size, unsigned int dontdo)
{
Base *base;
unsigned int *bufmin,*bufmax;
- int a,b,rc,tel,aantal,dirvec[4][2],maxob;
+ int a,b,rc,tel,len,dirvec[4][2],maxob;
unsigned int retval=0;
base= LASTBASE;
if(base==0) return 0;
maxob= base->selcol;
- aantal= (size-1)/2;
+ len= (size-1)/2;
rc= 0;
dirvec[0][0]= 1;
@@ -910,7 +910,7 @@ static unsigned int samplerect(unsigned int *buf, int size, unsigned int dontdo)
bufmin= buf;
bufmax= buf+ size*size;
- buf+= aantal*size+ aantal;
+ buf+= len*size+ len;
for(tel=1;tel<=size;tel++) {
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index eeaf87757ce..ed0b2645c99 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -1190,7 +1190,7 @@ int ED_view3d_lock(RegionView3D *rv3d)
return TRUE;
}
-/* dont set windows active in in here, is used by renderwin too */
+/* dont set windows active in here, is used by renderwin too */
void setviewmatrixview3d(Scene *scene, View3D *v3d, RegionView3D *rv3d)
{
if(rv3d->persp==RV3D_CAMOB) { /* obs/camera */
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index eea77e36f7c..39e26bc6436 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -1006,9 +1006,11 @@ int transformEvent(TransInfo *t, wmEvent *event)
else view_editmove(event->type);
t->redraw= 1;
break;
-// case NDOFMOTION:
-// viewmoveNDOF(1);
- // break;
+#if 0
+ case NDOF_MOTION:
+ // should have been caught by tranform_modal
+ return OPERATOR_PASS_THROUGH;
+#endif
default:
handled = 0;
break;
@@ -1017,43 +1019,6 @@ int transformEvent(TransInfo *t, wmEvent *event)
// Numerical input events
t->redraw |= handleNumInput(&(t->num), event);
- // NDof input events
- switch(handleNDofInput(&(t->ndof), event))
- {
- case NDOF_CONFIRM:
- if ((t->options & CTX_NDOF) == 0)
- {
- /* Confirm on normal transform only */
- t->state = TRANS_CONFIRM;
- }
- break;
- case NDOF_CANCEL:
- if (t->options & CTX_NDOF)
- {
- /* Cancel on pure NDOF transform */
- t->state = TRANS_CANCEL;
- }
- else
- {
- /* Otherwise, just redraw, NDof input was cancelled */
- t->redraw |= TREDRAW_HARD;
- }
- break;
- case NDOF_NOMOVE:
- if (t->options & CTX_NDOF)
- {
- /* Confirm on pure NDOF transform */
- t->state = TRANS_CONFIRM;
- }
- break;
- case NDOF_REFRESH:
- t->redraw |= TREDRAW_HARD;
- break;
- default:
- handled = 0;
- break;
- }
-
// Snapping events
t->redraw |= handleSnapping(t, event);
@@ -2886,10 +2851,6 @@ void initRotation(TransInfo *t)
setInputPostFct(&t->mouse, postInputRotation);
initMouseInputMode(t, &t->mouse, INPUT_ANGLE);
- t->ndof.axis = 16;
- /* Scale down and flip input for rotation */
- t->ndof.factor[0] = -0.2f;
-
t->idx_max = 0;
t->num.idx_max = 0;
t->snap[0] = 0.0f;
@@ -3161,8 +3122,6 @@ int Rotation(TransInfo *t, const int UNUSED(mval[2]))
final = t->values[0];
- applyNDofInput(&t->ndof, &final);
-
snapGrid(t, &final);
if ((t->con.mode & CON_APPLY) && t->con.applyRot) {
@@ -3216,11 +3175,6 @@ void initTrackball(TransInfo *t)
initMouseInputMode(t, &t->mouse, INPUT_TRACKBALL);
- t->ndof.axis = 40;
- /* Scale down input for rotation */
- t->ndof.factor[0] = 0.2f;
- t->ndof.factor[1] = 0.2f;
-
t->idx_max = 1;
t->num.idx_max = 1;
t->snap[0] = 0.0f;
@@ -3276,8 +3230,6 @@ int Trackball(TransInfo *t, const int UNUSED(mval[2]))
phi[0] = t->values[0];
phi[1] = t->values[1];
- applyNDofInput(&t->ndof, phi);
-
snapGrid(t, phi);
if (hasNumInput(&t->num)) {
@@ -3331,8 +3283,6 @@ void initTranslation(TransInfo *t)
t->num.flag = 0;
t->num.idx_max = t->idx_max;
- t->ndof.axis = (t->flag & T_2D_EDIT)? 1|2: 1|2|4;
-
if(t->spacetype == SPACE_VIEW3D) {
RegionView3D *rv3d = t->ar->regiondata;
@@ -3507,7 +3457,6 @@ int Translation(TransInfo *t, const int UNUSED(mval[2]))
headerTranslation(t, pvec, str);
}
else {
- applyNDofInput(&t->ndof, t->values);
snapGrid(t, t->values);
applyNumInput(&t->num, t->values);
if (hasNumInput(&t->num)) {
@@ -3616,10 +3565,6 @@ void initTilt(TransInfo *t)
initMouseInputMode(t, &t->mouse, INPUT_ANGLE);
- t->ndof.axis = 16;
- /* Scale down and flip input for rotation */
- t->ndof.factor[0] = -0.2f;
-
t->idx_max = 0;
t->num.idx_max = 0;
t->snap[0] = 0.0f;
@@ -3643,8 +3588,6 @@ int Tilt(TransInfo *t, const int UNUSED(mval[2]))
final = t->values[0];
- applyNDofInput(&t->ndof, &final);
-
snapGrid(t, &final);
if (hasNumInput(&t->num)) {
@@ -3759,10 +3702,6 @@ void initPushPull(TransInfo *t)
initMouseInputMode(t, &t->mouse, INPUT_VERTICAL_ABSOLUTE);
- t->ndof.axis = 4;
- /* Flip direction */
- t->ndof.factor[0] = -1.0f;
-
t->idx_max = 0;
t->num.idx_max = 0;
t->snap[0] = 0.0f;
@@ -3783,8 +3722,6 @@ int PushPull(TransInfo *t, const int UNUSED(mval[2]))
distance = t->values[0];
- applyNDofInput(&t->ndof, &distance);
-
snapGrid(t, &distance);
applyNumInput(&t->num, &distance);
@@ -4306,7 +4243,7 @@ static int createSlideVerts(TransInfo *t)
/* UV correction vars */
GHash **uvarray= NULL;
SlideData *sld = MEM_callocN(sizeof(*sld), "sld");
- int uvlay_tot= CustomData_number_of_layers(&em->fdata, CD_MTFACE);
+ const int uvlay_tot= (t->settings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT) ? CustomData_number_of_layers(&em->fdata, CD_MTFACE) : 0;
int uvlay_idx;
TransDataSlideUv *slideuvs=NULL, *suv=NULL, *suv_last=NULL;
RegionView3D *v3d = t->ar ? t->ar->regiondata : NULL; /* background mode support */
@@ -4659,7 +4596,7 @@ static int createSlideVerts(TransInfo *t)
#define EDGE_SLIDE_MIN 30
if (len_squared_v2v2(start, end) < (EDGE_SLIDE_MIN * EDGE_SLIDE_MIN)) {
if(ABS(start[0]-end[0]) + ABS(start[1]-end[1]) < 4.0f) {
- /* even more exceptional case, points are ontop of eachother */
+ /* even more exceptional case, points are ontop of each other */
end[0]= start[0];
end[1]= start[1] + EDGE_SLIDE_MIN;
}
@@ -4678,7 +4615,7 @@ static int createSlideVerts(TransInfo *t)
sld->end[0] = (int) end[0];
sld->end[1] = (int) end[1];
- if (uvlay_tot) { // XXX && (scene->toolsettings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT)) {
+ if (uvlay_tot) {
int maxnum = 0;
uvarray = MEM_callocN( uvlay_tot * sizeof(GHash *), "SlideUVs Array");
@@ -4868,8 +4805,6 @@ void initEdgeSlide(TransInfo *t)
int doEdgeSlide(TransInfo *t, float perc)
{
- Mesh *me= t->obedit->data;
- EditMesh *em = me->edit_mesh;
SlideData *sld = t->customData;
EditVert *ev, *nearest = sld->nearest;
EditVert *centerVert, *upVert, *downVert;
@@ -4880,7 +4815,7 @@ int doEdgeSlide(TransInfo *t, float perc)
int prop=1, flip=0;
/* UV correction vars */
GHash **uvarray= sld->uvhash;
- int uvlay_tot= CustomData_number_of_layers(&em->fdata, CD_MTFACE);
+ const int uvlay_tot= sld->uvlay_tot;
int uvlay_idx;
TransDataSlideUv *suv;
float uv_tmp[2];
@@ -4906,7 +4841,7 @@ int doEdgeSlide(TransInfo *t, float perc)
tempev = editedge_getOtherVert((perc>=0)?tempsv->up:tempsv->down, ev);
interp_v3_v3v3(ev->co, tempsv->origvert.co, tempev->co, fabs(perc));
- if (uvlay_tot) { // XXX scene->toolsettings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT) {
+ if (uvlay_tot) {
for (uvlay_idx=0; uvlay_idx<uvlay_tot; uvlay_idx++) {
suv = BLI_ghash_lookup( uvarray[uvlay_idx], ev );
if (suv && suv->fuv_list && suv->uv_up && suv->uv_down) {
@@ -4936,7 +4871,7 @@ int doEdgeSlide(TransInfo *t, float perc)
if(newlen < 0.0f) {newlen = 0.0;}
if(flip == 0) {
interp_v3_v3v3(ev->co, editedge_getOtherVert(tempsv->down,ev)->co, editedge_getOtherVert(tempsv->up,ev)->co, fabs(newlen));
- if (uvlay_tot) { // XXX scene->toolsettings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT) {
+ if (uvlay_tot) {
/* dont do anything if no UVs */
for (uvlay_idx=0; uvlay_idx<uvlay_tot; uvlay_idx++) {
suv = BLI_ghash_lookup( uvarray[uvlay_idx], ev );
@@ -4953,7 +4888,7 @@ int doEdgeSlide(TransInfo *t, float perc)
} else{
interp_v3_v3v3(ev->co, editedge_getOtherVert(tempsv->up,ev)->co, editedge_getOtherVert(tempsv->down,ev)->co, fabs(newlen));
- if (uvlay_tot) { // XXX scene->toolsettings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT) {
+ if (uvlay_tot) {
/* dont do anything if no UVs */
for (uvlay_idx=0; uvlay_idx<uvlay_tot; uvlay_idx++) {
suv = BLI_ghash_lookup( uvarray[uvlay_idx], ev );
@@ -5309,8 +5244,6 @@ void initSeqSlide(TransInfo *t)
t->num.flag = 0;
t->num.idx_max = t->idx_max;
- t->ndof.axis = 1|2;
-
t->snap[0] = 0.0f;
t->snap[1] = floor(t->scene->r.frs_sec / t->scene->r.frs_sec_base);
t->snap[2] = 10.0f;
@@ -5365,7 +5298,6 @@ int SeqSlide(TransInfo *t, const int UNUSED(mval[2]))
VECCOPY(t->values, tvec);
}
else {
- applyNDofInput(&t->ndof, t->values);
snapGrid(t, t->values);
applyNumInput(&t->num, t->values);
}
@@ -5925,54 +5857,3 @@ void BIF_TransformSetUndo(char *UNUSED(str))
// TRANSFORM_FIX_ME
//Trans.undostr= str;
}
-
-
-#if 0 // TRANSFORM_FIX_ME
-static void NDofTransform(void)
-{
- float fval[7];
- float maxval = 50.0f; // also serves as threshold
- int axis = -1;
- int mode = 0;
- int i;
-
- getndof(fval);
-
- for(i = 0; i < 6; i++)
- {
- float val = fabs(fval[i]);
- if (val > maxval)
- {
- axis = i;
- maxval = val;
- }
- }
-
- switch(axis)
- {
- case -1:
- /* No proper axis found */
- break;
- case 0:
- case 1:
- case 2:
- mode = TFM_TRANSLATION;
- break;
- case 4:
- mode = TFM_ROTATION;
- break;
- case 3:
- case 5:
- mode = TFM_TRACKBALL;
- break;
- default:
- printf("ndof: what we are doing here ?");
- }
-
- if (mode != 0)
- {
- initTransform(mode, CTX_NDOF);
- Transform();
- }
-}
-#endif
diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h
index d8e750acb88..d8e42488787 100644
--- a/source/blender/editors/transform/transform.h
+++ b/source/blender/editors/transform/transform.h
@@ -96,7 +96,7 @@ typedef struct TransSnap {
short modeSelect;
short align;
char project;
- char project_self;
+ char snap_self;
short peel;
short status;
float snapPoint[3]; /* snapping from this point */
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index 20a26d8c58d..c81c398e696 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -887,6 +887,7 @@ void resetTransRestrictions(TransInfo *t)
t->flag &= ~T_ALL_RESTRICTIONS;
}
+/* the *op can be NULL */
int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event)
{
Scene *sce = CTX_data_scene(C);
@@ -1013,6 +1014,22 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event)
t->options |= CTX_NO_PET;
}
}
+
+ /* initialize UV transform from */
+ if (op && RNA_struct_find_property(op->ptr, "correct_uv")) {
+ if(RNA_property_is_set(op->ptr, "correct_uv")) {
+ if(RNA_boolean_get(op->ptr, "correct_uv")) {
+ t->settings->uvcalc_flag |= UVCALC_TRANSFORM_CORRECT;
+ }
+ else {
+ t->settings->uvcalc_flag &= ~UVCALC_TRANSFORM_CORRECT;
+ }
+ }
+ else {
+ RNA_boolean_set(op->ptr, "correct_uv", t->settings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT);
+ }
+ }
+
}
else if(t->spacetype==SPACE_IMAGE)
{
@@ -1070,7 +1087,7 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event)
}
}
// Need stuff to take it from edit mesh or whatnot here
- else
+ else if (t->spacetype == SPACE_VIEW3D)
{
if (t->obedit && t->obedit->type == OB_MESH && (((Mesh *)t->obedit->data)->editflag & ME_EDIT_MIRROR_X))
{
diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c
index 2d0c1ac2818..54e0b31e201 100644
--- a/source/blender/editors/transform/transform_ops.c
+++ b/source/blender/editors/transform/transform_ops.c
@@ -360,6 +360,18 @@ static int transform_modal(bContext *C, wmOperator *op, wmEvent *event)
TransInfo *t = op->customdata;
+ #if 0
+ // stable 2D mouse coords map to different 3D coords while the 3D mouse is active
+ // in other words, 2D deltas are no longer good enough!
+ // disable until individual 'transformers' behave better
+
+ if (event->type == NDOF_MOTION)
+ {
+ /* puts("transform_modal: passing through NDOF_MOTION"); */
+ return OPERATOR_PASS_THROUGH;
+ }
+ #endif
+
/* XXX insert keys are called here, and require context */
t->context= C;
exit_code = transformEvent(t, event);
@@ -496,6 +508,11 @@ void Transform_Properties(struct wmOperatorType *ot, int flags)
RNA_def_boolean(ot->srna, "texture_space", 0, "Edit Object data texture space", "");
}
+ if (flags & P_CORRECT_UV)
+ {
+ RNA_def_boolean(ot->srna, "correct_uv", 0, "Correct UV coords when transforming", "");
+ }
+
// Add confirm method all the time. At the end because it's not really that important and should be hidden only in log, not in keymap edit
/*prop =*/ RNA_def_boolean(ot->srna, "release_confirm", 0, "Confirm on Release", "Always confirm operation when releasing button");
//RNA_def_property_flag(prop, PROP_HIDDEN);
@@ -743,7 +760,7 @@ void TRANSFORM_OT_edge_slide(struct wmOperatorType *ot)
RNA_def_float_factor(ot->srna, "value", 0, -1.0f, 1.0f, "Factor", "", -1.0f, 1.0f);
- Transform_Properties(ot, P_MIRROR|P_SNAP);
+ Transform_Properties(ot, P_MIRROR|P_SNAP|P_CORRECT_UV);
}
void TRANSFORM_OT_edge_crease(struct wmOperatorType *ot)
diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c
index d9d9b0f9102..ca89670dedb 100644
--- a/source/blender/editors/transform/transform_snap.c
+++ b/source/blender/editors/transform/transform_snap.c
@@ -392,7 +392,7 @@ static void initSnappingMode(TransInfo *t)
}
else
{
- t->tsnap.modeSelect = t->tsnap.project_self ? SNAP_ALL : SNAP_NOT_OBEDIT;
+ t->tsnap.modeSelect = t->tsnap.snap_self ? SNAP_ALL : SNAP_NOT_OBEDIT;
}
}
/* Particles edit mode*/
@@ -458,23 +458,26 @@ void initSnapping(TransInfo *t, wmOperator *op)
t->tsnap.project = RNA_boolean_get(op->ptr, "use_snap_project");
}
- if (RNA_struct_find_property(op->ptr, "use_snap_project_self"))
+ if (RNA_struct_find_property(op->ptr, "use_snap_self"))
{
- t->tsnap.project = RNA_boolean_get(op->ptr, "use_snap_project_self");
+ t->tsnap.snap_self = RNA_boolean_get(op->ptr, "use_snap_self");
}
}
}
/* use scene defaults only when transform is modal */
else if (t->flag & T_MODAL)
{
- if (ts->snap_flag & SCE_SNAP) {
- t->modifiers |= MOD_SNAP;
- }
+ if(ELEM(t->spacetype, SPACE_VIEW3D, SPACE_IMAGE))
+ {
+ if (ts->snap_flag & SCE_SNAP) {
+ t->modifiers |= MOD_SNAP;
+ }
- t->tsnap.align = ((t->settings->snap_flag & SCE_SNAP_ROTATE) == SCE_SNAP_ROTATE);
- t->tsnap.project = ((t->settings->snap_flag & SCE_SNAP_PROJECT) == SCE_SNAP_PROJECT);
- t->tsnap.project_self = !((t->settings->snap_flag & SCE_SNAP_PROJECT_NO_SELF) == SCE_SNAP_PROJECT_NO_SELF);
- t->tsnap.peel = ((t->settings->snap_flag & SCE_SNAP_PROJECT) == SCE_SNAP_PROJECT);
+ t->tsnap.align = ((t->settings->snap_flag & SCE_SNAP_ROTATE) == SCE_SNAP_ROTATE);
+ t->tsnap.project = ((t->settings->snap_flag & SCE_SNAP_PROJECT) == SCE_SNAP_PROJECT);
+ t->tsnap.snap_self = !((t->settings->snap_flag & SCE_SNAP_NO_SELF) == SCE_SNAP_NO_SELF);
+ t->tsnap.peel = ((t->settings->snap_flag & SCE_SNAP_PROJECT) == SCE_SNAP_PROJECT);
+ }
}
t->tsnap.target = snap_target;
@@ -1944,6 +1947,11 @@ static void applyGrid(TransInfo *t, float *val, int max_index, float fac[3], Gea
int i;
float asp[3] = {1.0f, 1.0f, 1.0f}; // TODO: Remove hard coded limit here (3)
+ if(max_index > 2) {
+ printf("applyGrid: invalid index %d, clamping\n", max_index);
+ max_index= 2;
+ }
+
// Early bailing out if no need to snap
if (fac[action] == 0.0f)
return;
diff --git a/source/blender/editors/util/undo.c b/source/blender/editors/util/undo.c
index 8a6ec7f75db..a2381a208ef 100644
--- a/source/blender/editors/util/undo.c
+++ b/source/blender/editors/util/undo.c
@@ -358,19 +358,25 @@ int ED_undo_operator_repeat(bContext *C, struct wmOperator *op)
ret= 1;
}
}
+ else {
+ if (G.f & G_DEBUG) {
+ printf("redo_cb: WM_operator_repeat_check returned false %s\n", op->type->name);
+ }
+ }
/* set region back */
CTX_wm_region_set(C, ar);
}
else {
if (G.f & G_DEBUG) {
- printf("redo_cb: WM_operator_repeat_check returned false %s\n", op->type->name);
+ printf("redo_cb: ED_undo_operator_repeat called with NULL 'op'\n");
}
}
return ret;
}
+
void ED_undo_operator_repeat_cb(bContext *C, void *arg_op, void *UNUSED(arg_unused))
{
ED_undo_operator_repeat(C, (wmOperator *)arg_op);
diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c
index d0393c970a6..70659994c55 100644
--- a/source/blender/editors/uvedit/uvedit_ops.c
+++ b/source/blender/editors/uvedit/uvedit_ops.c
@@ -1060,8 +1060,8 @@ static void weld_align_uv(bContext *C, int tool)
if(tool == 's' || tool == 't' || tool == 'u') {
/* pass 1&2 variables */
int i, j;
- int starttmpl= -1, connectedtostarttmpl, startcorner;
- int endtmpl= -1, connectedtoendtmpl, endcorner;
+ int starttmpl= -1, connectedtostarttmpl= -1, startcorner;
+ int endtmpl= -1, connectedtoendtmpl= -1, endcorner;
MTFace *startface, *endface;
int itmpl, jtmpl;
EditVert *eve;
diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c
index 3804aad6848..274884000db 100644
--- a/source/blender/gpu/intern/gpu_material.c
+++ b/source/blender/gpu/intern/gpu_material.c
@@ -671,7 +671,7 @@ static void shade_one_light(GPUShadeInput *shi, GPUShadeResult *shr, GPULamp *la
i = is;
GPU_link(mat, "shade_visifac", i, visifac, shi->refl, &i);
- vn = shi->vn;
+
/*if(ma->mode & MA_TANGENT_VN)
GPU_link(mat, "shade_tangent_v_spec", GPU_attribute(CD_TANGENT, ""), &vn);*/
@@ -1371,9 +1371,6 @@ void GPU_shaderesult_set(GPUShadeInput *shi, GPUShadeResult *shr)
mat->obcolalpha = 1;
GPU_link(mat, "shade_alpha_obcolor", shr->combined, GPU_builtin(GPU_OBCOLOR), &shr->combined);
}
-
- if(gpu_do_color_management(mat))
- GPU_link(mat, "linearrgb_to_srgb", shr->combined, &shr->combined);
}
static GPUNodeLink *GPU_blender_material(GPUMaterial *mat, Material *ma)
@@ -1408,6 +1405,10 @@ GPUMaterial *GPU_material_from_blender(Scene *scene, Material *ma)
GPU_material_output_link(mat, outlink);
}
+ if(gpu_do_color_management(mat))
+ if(mat->outlink)
+ GPU_link(mat, "linearrgb_to_srgb", mat->outlink, &mat->outlink);
+
/*if(!GPU_material_construct_end(mat)) {
GPU_material_free(mat);
mat= NULL;
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index 02d158a3f3a..05730576c4a 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -625,6 +625,7 @@ typedef struct MultiresModifierData {
typedef enum {
eMultiresModifierFlag_ControlEdges = (1<<0),
+ eMultiresModifierFlag_PlainUv = (1<<1),
} MultiresModifierFlag;
typedef struct FluidsimModifierData {
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index 8203a4dd77c..2211f93a8ae 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -1074,7 +1074,7 @@ typedef struct Scene {
#define SCE_SNAP_ROTATE 2
#define SCE_SNAP_PEEL_OBJECT 4
#define SCE_SNAP_PROJECT 8
-#define SCE_SNAP_PROJECT_NO_SELF 16
+#define SCE_SNAP_NO_SELF 16
/* toolsettings->snap_target */
#define SCE_SNAP_TARGET_CLOSEST 0
#define SCE_SNAP_TARGET_CENTER 1
diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h
index ae57cf3f80b..0bf812f1ec2 100644
--- a/source/blender/makesdna/DNA_userdef_types.h
+++ b/source/blender/makesdna/DNA_userdef_types.h
@@ -365,7 +365,6 @@ typedef struct UserDef {
short recent_files; /* maximum number of recently used files to remember */
short smooth_viewtx; /* miliseconds to spend spinning the view */
short glreslimit;
- short ndof_pan, ndof_rotate;
short curssize;
short color_picker_type;
short ipo_new; /* interpolation mode for newly added F-Curves */
@@ -376,6 +375,10 @@ typedef struct UserDef {
short widget_unit; /* defaults to 20 for 72 DPI setting */
short anisotropic_filter;
+ /*short pad[3]; */
+
+ float ndof_sensitivity; /* overall sensitivity of 3D mouse */
+ int ndof_flag; /* flags for 3D mouse */
char versemaster[160];
char verseuser[160];
@@ -384,7 +387,7 @@ typedef struct UserDef {
short autokey_mode; /* autokeying mode */
short autokey_flag; /* flags for autokeying */
- short text_render, pad9; /*options for text rendering*/
+ short text_render, pad9[3]; /*options for text rendering*/
struct ColorBand coba_weight; /* from texture.h */
@@ -577,6 +580,31 @@ extern UserDef U; /* from blenkernel blender.c */
#define TH_OLDSKOOL 3
#define TH_SHADED 4
+/* ndof_flag (3D mouse options) */
+#define NDOF_SHOW_GUIDE (1 << 0)
+#define NDOF_FLY_HELICOPTER (1 << 1)
+#define NDOF_LOCK_HORIZON (1 << 2)
+/* the following might not need to be saved between sessions,
+ but they do need to live somewhere accessible... */
+#define NDOF_SHOULD_PAN (1 << 3)
+#define NDOF_SHOULD_ZOOM (1 << 4)
+#define NDOF_SHOULD_ROTATE (1 << 5)
+/* orbit navigation modes
+ only two options, so it's sort of a hyrbrid bool/enum
+ if ((U.ndof_flag & NDOF_ORBIT_MODE) == NDOF_OM_OBJECT)... */
+/*
+#define NDOF_ORBIT_MODE (1 << 6)
+#define NDOF_OM_TARGETCAMERA 0
+#define NDOF_OM_OBJECT NDOF_ORBIT_MODE
+*/
+/* actually... users probably don't care about what the mode
+ is called, just that it feels right */
+#define NDOF_ORBIT_INVERT_AXES (1 << 6)
+/* zoom is up/down if this flag is set (otherwise forward/backward) */
+#define NDOF_ZOOM_UPDOWN (1 << 7)
+#define NDOF_INVERT_ZOOM (1 << 8)
+
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h
index 7379493003d..89b8bad2806 100644
--- a/source/blender/makesdna/DNA_view3d_types.h
+++ b/source/blender/makesdna/DNA_view3d_types.h
@@ -130,7 +130,11 @@ typedef struct RegionView3D {
float twangle[3];
- float padf;
+ /* active rotation from NDOF or elsewhere */
+ float rot_angle;
+ float rot_axis[3];
+
+ char pad2[4];
} RegionView3D;
@@ -190,11 +194,10 @@ typedef struct View3D {
/* drawflags, denoting state */
short zbuf, transp, xray;
- char ndofmode; /* mode of transform for 6DOF devices -1 not found, 0 normal, 1 fly, 2 ob transform */
- char ndoffilter; /* filter for 6DOF devices 0 normal, 1 dominant */
-
+ char pad3[2];
+
void *properties_storage; /* Nkey panel stores stuff here (runtime only!) */
-
+
/* XXX depricated? */
struct bGPdata *gpd; /* Grease-Pencil Data (annotation layers) */
diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c
index 3ce84e3a19f..8d57403ec35 100644
--- a/source/blender/makesrna/intern/rna_ID.c
+++ b/source/blender/makesrna/intern/rna_ID.c
@@ -35,6 +35,7 @@
#include "DNA_ID.h"
#include "DNA_vfont_types.h"
+#include "DNA_material_types.h"
#include "DNA_object_types.h"
#include "WM_types.h"
@@ -416,8 +417,9 @@ static void rna_def_ID_materials(BlenderRNA *brna)
func= RNA_def_function(srna, "pop", "material_pop_id");
RNA_def_function_ui_description(func, "Remove a material from the data block.");
- parm= RNA_def_int(func, "index", 0, 0, INT_MAX, "", "Index of material to remove.", 0, INT_MAX);
+ parm= RNA_def_int(func, "index", 0, 0, MAXMAT, "", "Index of material to remove.", 0, MAXMAT);
RNA_def_property_flag(parm, PROP_REQUIRED);
+ RNA_def_boolean(func, "update_data", 0, "", "Update data by re-adjusting the material slots assigned.");
parm= RNA_def_pointer(func, "material", "Material", "", "Material to remove.");
RNA_def_function_return(func, parm);
}
diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c
index d9fbdd7caf2..e71be8c153e 100644
--- a/source/blender/makesrna/intern/rna_access.c
+++ b/source/blender/makesrna/intern/rna_access.c
@@ -1364,13 +1364,13 @@ static void rna_property_update(bContext *C, Main *bmain, Scene *scene, PointerR
if(prop->noteflag)
WM_main_add_notifier(prop->noteflag, ptr->id.data);
}
- else {
+
+ if(!is_rna || (prop->flag & PROP_IDPROPERTY)) {
/* WARNING! This is so property drivers update the display!
* not especially nice */
DAG_id_tag_update(ptr->id.data, OB_RECALC_OB|OB_RECALC_DATA|OB_RECALC_TIME);
WM_main_add_notifier(NC_WINDOW, NULL);
}
-
}
/* must keep in sync with 'rna_property_update'
@@ -4407,15 +4407,15 @@ ParameterList *RNA_parameter_list_create(ParameterList *parms, PointerRNA *UNUSE
if(!(parm->flag & PROP_REQUIRED) && !(parm->flag & PROP_DYNAMIC)) {
switch(parm->type) {
case PROP_BOOLEAN:
- if(parm->arraydimension) memcpy(data, &((BooleanPropertyRNA*)parm)->defaultarray, size);
+ if(parm->arraydimension) memcpy(data, ((BooleanPropertyRNA*)parm)->defaultarray, size);
else memcpy(data, &((BooleanPropertyRNA*)parm)->defaultvalue, size);
break;
case PROP_INT:
- if(parm->arraydimension) memcpy(data, &((IntPropertyRNA*)parm)->defaultarray, size);
+ if(parm->arraydimension) memcpy(data, ((IntPropertyRNA*)parm)->defaultarray, size);
else memcpy(data, &((IntPropertyRNA*)parm)->defaultvalue, size);
break;
case PROP_FLOAT:
- if(parm->arraydimension) memcpy(data, &((FloatPropertyRNA*)parm)->defaultarray, size);
+ if(parm->arraydimension) memcpy(data, ((FloatPropertyRNA*)parm)->defaultarray, size);
else memcpy(data, &((FloatPropertyRNA*)parm)->defaultvalue, size);
break;
case PROP_ENUM:
diff --git a/source/blender/makesrna/intern/rna_action.c b/source/blender/makesrna/intern/rna_action.c
index 7fdb96fda6e..cfedee3c6cd 100644
--- a/source/blender/makesrna/intern/rna_action.c
+++ b/source/blender/makesrna/intern/rna_action.c
@@ -191,8 +191,9 @@ static void rna_Action_active_pose_marker_index_range(PointerRNA *ptr, int *min,
static void rna_Action_frame_range_get(PointerRNA *ptr,float *values)
-{
- calc_action_range(ptr->id.data, values, values+1, 1);
+{ /* don't include modifiers because they too easily can have very large
+ * ranges: MINAFRAMEF to MAXFRAMEF. */
+ calc_action_range(ptr->id.data, values, values+1, FALSE);
}
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index f2b4dd8711c..3571ff3c266 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -810,6 +810,11 @@ static void rna_def_modifier_multires(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flags", eMultiresModifierFlag_ControlEdges);
RNA_def_property_ui_text(prop, "Optimal Display", "Skip drawing/rendering of interior subdivided edges");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop= RNA_def_property(srna, "use_subsurf_uv", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_negative_sdna(prop, NULL, "flags", eMultiresModifierFlag_PlainUv);
+ RNA_def_property_ui_text(prop, "Subdivide UVs", "Use subsurf to subdivide UVs");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
}
static void rna_def_modifier_lattice(BlenderRNA *brna)
diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c
index 9018fd8c71a..21fa28af01a 100644
--- a/source/blender/makesrna/intern/rna_object_api.c
+++ b/source/blender/makesrna/intern/rna_object_api.c
@@ -544,7 +544,7 @@ void RNA_api_object(StructRNA *srna)
/* location of point for test and max distance */
parm= RNA_def_float_vector(func, "point", 3, NULL, -FLT_MAX, FLT_MAX, "", "", -1e4, 1e4);
RNA_def_property_flag(parm, PROP_REQUIRED);
- parm= RNA_def_float(func, "max_dist", sqrt(FLT_MAX), 0.0, FLT_MAX, "", "", 0.0, FLT_MAX);
+ RNA_def_float(func, "max_dist", sqrt(FLT_MAX), 0.0, FLT_MAX, "", "", 0.0, FLT_MAX);
/* return location and normal */
parm= RNA_def_float_vector(func, "location", 3, NULL, -FLT_MAX, FLT_MAX, "Location", "The location on the object closest to the point", -1e4, 1e4);
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index d9475eaa683..b3d8bc8ea18 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -1178,9 +1178,9 @@ static void rna_def_tool_settings(BlenderRNA *brna)
RNA_def_property_ui_icon(prop, ICON_RETOPO, 0);
RNA_def_property_update(prop, NC_SCENE|ND_TOOLSETTINGS, NULL); /* header redraw */
- prop= RNA_def_property(srna, "use_snap_project_self", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_negative_sdna(prop, NULL, "snap_flag", SCE_SNAP_PROJECT_NO_SELF);
- RNA_def_property_ui_text(prop, "Project to Self", "Project into its self (editmode)");
+ prop= RNA_def_property(srna, "use_snap_self", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_negative_sdna(prop, NULL, "snap_flag", SCE_SNAP_NO_SELF);
+ RNA_def_property_ui_text(prop, "Project to Self", "Snap onto its self (editmode)");
RNA_def_property_ui_icon(prop, ICON_ORTHO, 0);
RNA_def_property_update(prop, NC_SCENE|ND_TOOLSETTINGS, NULL); /* header redraw */
@@ -3251,7 +3251,7 @@ void RNA_def_scene(BlenderRNA *brna)
RNA_def_property_int_sdna(prop, NULL, "r.cfra");
RNA_def_property_range(prop, MINAFRAME, MAXFRAME);
RNA_def_property_int_funcs(prop, NULL, "rna_Scene_current_frame_set", NULL);
- RNA_def_property_ui_text(prop, "Current Frame", "Current Frame");
+ RNA_def_property_ui_text(prop, "Current Frame", "Current Frame, to update animation data from python frame_set() instead");
RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_update(prop, NC_SCENE|ND_FRAME, "rna_Scene_frame_update");
diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c
index 4d1e1f175f2..7a9193571fd 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -2737,17 +2737,30 @@ static void rna_def_userdef_input(BlenderRNA *brna)
RNA_def_property_int_sdna(prop, NULL, "dragthreshold");
RNA_def_property_range(prop, 3, 40);
RNA_def_property_ui_text(prop, "Drag Threshold", "Amount of pixels you have to drag before dragging UI items happens");
-
- prop= RNA_def_property(srna, "ndof_pan_speed", PROP_INT, PROP_NONE);
- RNA_def_property_int_sdna(prop, NULL, "ndof_pan");
- RNA_def_property_range(prop, 0, 200);
- RNA_def_property_ui_text(prop, "NDof Pan Speed", "The overall panning speed of an NDOF device, as percent of standard");
- prop= RNA_def_property(srna, "ndof_rotate_speed", PROP_INT, PROP_NONE);
- RNA_def_property_int_sdna(prop, NULL, "ndof_rotate");
- RNA_def_property_range(prop, 0, 200);
- RNA_def_property_ui_text(prop, "NDof Rotation Speed", "The overall rotation speed of an NDOF device, as percent of standard");
-
+ /* 3D mouse settings */
+ prop= RNA_def_property(srna, "ndof_sensitivity", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_range(prop, 0.25f, 4.0f);
+ RNA_def_property_ui_text(prop, "Sensitivity", "Overall sensitivity of the 3D Mouse");
+
+ prop= RNA_def_property(srna, "ndof_show_guide", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "ndof_flag", NDOF_SHOW_GUIDE);
+ RNA_def_property_ui_text(prop, "Show Navigation Guide", "Display the center and axis during rotation");
+ /* TODO: update description when fly-mode visuals are in place ("projected position in fly mode")*/
+
+ prop= RNA_def_property(srna, "ndof_orbit_invert_axes", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "ndof_flag", NDOF_ORBIT_INVERT_AXES);
+ RNA_def_property_ui_text(prop, "Invert Axes", "Toggle between moving the viewpoint or moving the scene being viewed");
+
+ prop= RNA_def_property(srna, "ndof_lock_horizon", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "ndof_flag", NDOF_LOCK_HORIZON);
+ RNA_def_property_ui_text(prop, "Lock Horizon", "Keep horizon level while flying with 3D Mouse");
+
+ prop= RNA_def_property(srna, "ndof_fly_helicopter", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "ndof_flag", NDOF_FLY_HELICOPTER);
+ RNA_def_property_ui_text(prop, "Helicopter Mode", "Device up/down directly controls your Z position");
+
+
prop= RNA_def_property(srna, "mouse_double_click_time", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "dbl_click_time");
RNA_def_property_range(prop, 1, 1000);
diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c
index 7ea4701dec3..a046be59ab5 100644
--- a/source/blender/makesrna/intern/rna_wm.c
+++ b/source/blender/makesrna/intern/rna_wm.c
@@ -106,6 +106,46 @@ EnumPropertyItem event_timer_type_items[]= {
{TIMER2, "TIMER2", 0, "Timer 2", ""},
{0, NULL, 0, NULL, NULL}};
+EnumPropertyItem event_ndof_type_items[]= {
+ /* buttons on all 3dconnexion devices */
+ {NDOF_BUTTON_MENU, "NDOF_BUTTON_MENU", 0, "Menu", ""},
+ {NDOF_BUTTON_FIT, "NDOF_BUTTON_FIT", 0, "Fit", ""},
+ /* view buttons */
+ {NDOF_BUTTON_TOP, "NDOF_BUTTON_TOP", 0, "Top", ""},
+ {NDOF_BUTTON_BOTTOM, "NDOF_BUTTON_BOTTOM", 0, "Bottom", ""},
+ {NDOF_BUTTON_LEFT, "NDOF_BUTTON_LEFT", 0, "Left", ""},
+ {NDOF_BUTTON_RIGHT, "NDOF_BUTTON_RIGHT", 0, "Right", ""},
+ {NDOF_BUTTON_FRONT, "NDOF_BUTTON_FRONT", 0, "Front", ""},
+ {NDOF_BUTTON_BACK, "NDOF_BUTTON_BACK", 0, "Back", ""},
+ /* more views */
+ {NDOF_BUTTON_ISO1, "NDOF_BUTTON_ISO1", 0, "ISO 1", ""},
+ {NDOF_BUTTON_ISO2, "NDOF_BUTTON_ISO2", 0, "ISO 2", ""},
+ /* 90 degree rotations */
+ {NDOF_BUTTON_ROLL_CW, "NDOF_BUTTON_ROLL_CW", 0, "Roll CW", ""},
+ {NDOF_BUTTON_ROLL_CCW, "NDOF_BUTTON_ROLL_CCW", 0, "Roll CCW", ""},
+ {NDOF_BUTTON_SPIN_CW, "NDOF_BUTTON_SPIN_CW", 0, "Spin CW", ""},
+ {NDOF_BUTTON_SPIN_CCW, "NDOF_BUTTON_SPIN_CCW", 0, "Spin CCW", ""},
+ {NDOF_BUTTON_TILT_CW, "NDOF_BUTTON_TILT_CW", 0, "Tilt CW", ""},
+ {NDOF_BUTTON_TILT_CCW, "NDOF_BUTTON_TILT_CCW", 0, "Tilt CCW", ""},
+ /* device control */
+ {NDOF_BUTTON_ROTATE, "NDOF_BUTTON_ROTATE", 0, "Rotate", ""},
+ {NDOF_BUTTON_PANZOOM, "NDOF_BUTTON_PANZOOM", 0, "Pan/Zoom", ""},
+ {NDOF_BUTTON_DOMINANT, "NDOF_BUTTON_DOMINANT", 0, "Dominant", ""},
+ {NDOF_BUTTON_PLUS, "NDOF_BUTTON_PLUS", 0, "Plus", ""},
+ {NDOF_BUTTON_MINUS, "NDOF_BUTTON_MINUS", 0, "Minus", ""},
+ /* general-purpose buttons */
+ {NDOF_BUTTON_1, "NDOF_BUTTON_1", 0, "Button 1", ""},
+ {NDOF_BUTTON_2, "NDOF_BUTTON_2", 0, "Button 2", ""},
+ {NDOF_BUTTON_3, "NDOF_BUTTON_3", 0, "Button 3", ""},
+ {NDOF_BUTTON_4, "NDOF_BUTTON_4", 0, "Button 4", ""},
+ {NDOF_BUTTON_5, "NDOF_BUTTON_5", 0, "Button 5", ""},
+ {NDOF_BUTTON_6, "NDOF_BUTTON_6", 0, "Button 6", ""},
+ {NDOF_BUTTON_7, "NDOF_BUTTON_7", 0, "Button 7", ""},
+ {NDOF_BUTTON_8, "NDOF_BUTTON_8", 0, "Button 8", ""},
+ {NDOF_BUTTON_9, "NDOF_BUTTON_9", 0, "Button 9", ""},
+ {NDOF_BUTTON_10, "NDOF_BUTTON_10", 0, "Button 10", ""},
+ {0, NULL, 0, NULL, NULL}};
+
/* not returned: CAPSLOCKKEY, UNKNOWNKEY */
EnumPropertyItem event_type_items[] = {
@@ -256,6 +296,44 @@ EnumPropertyItem event_type_items[] = {
{TIMER0, "TIMER0", 0, "Timer 0", ""},
{TIMER1, "TIMER1", 0, "Timer 1", ""},
{TIMER2, "TIMER2", 0, "Timer 2", ""},
+ {0, "", 0, NULL, NULL},
+ /* buttons on all 3dconnexion devices */
+ {NDOF_BUTTON_MENU, "NDOF_BUTTON_MENU", 0, "Menu", ""},
+ {NDOF_BUTTON_FIT, "NDOF_BUTTON_FIT", 0, "Fit", ""},
+ /* view buttons */
+ {NDOF_BUTTON_TOP, "NDOF_BUTTON_TOP", 0, "Top", ""},
+ {NDOF_BUTTON_BOTTOM, "NDOF_BUTTON_BOTTOM", 0, "Bottom", ""},
+ {NDOF_BUTTON_LEFT, "NDOF_BUTTON_LEFT", 0, "Left", ""},
+ {NDOF_BUTTON_RIGHT, "NDOF_BUTTON_RIGHT", 0, "Right", ""},
+ {NDOF_BUTTON_FRONT, "NDOF_BUTTON_FRONT", 0, "Front", ""},
+ {NDOF_BUTTON_BACK, "NDOF_BUTTON_BACK", 0, "Back", ""},
+ /* more views */
+ {NDOF_BUTTON_ISO1, "NDOF_BUTTON_ISO1", 0, "ISO 1", ""},
+ {NDOF_BUTTON_ISO2, "NDOF_BUTTON_ISO2", 0, "ISO 2", ""},
+ /* 90 degree rotations */
+ {NDOF_BUTTON_ROLL_CW, "NDOF_BUTTON_ROLL_CW", 0, "Roll CW", ""},
+ {NDOF_BUTTON_ROLL_CCW, "NDOF_BUTTON_ROLL_CCW", 0, "Roll CCW", ""},
+ {NDOF_BUTTON_SPIN_CW, "NDOF_BUTTON_SPIN_CW", 0, "Spin CW", ""},
+ {NDOF_BUTTON_SPIN_CCW, "NDOF_BUTTON_SPIN_CCW", 0, "Spin CCW", ""},
+ {NDOF_BUTTON_TILT_CW, "NDOF_BUTTON_TILT_CW", 0, "Tilt CW", ""},
+ {NDOF_BUTTON_TILT_CCW, "NDOF_BUTTON_TILT_CCW", 0, "Tilt CCW", ""},
+ /* device control */
+ {NDOF_BUTTON_ROTATE, "NDOF_BUTTON_ROTATE", 0, "Rotate", ""},
+ {NDOF_BUTTON_PANZOOM, "NDOF_BUTTON_PANZOOM", 0, "Pan/Zoom", ""},
+ {NDOF_BUTTON_DOMINANT, "NDOF_BUTTON_DOMINANT", 0, "Dominant", ""},
+ {NDOF_BUTTON_PLUS, "NDOF_BUTTON_PLUS", 0, "Plus", ""},
+ {NDOF_BUTTON_MINUS, "NDOF_BUTTON_MINUS", 0, "Minus", ""},
+ /* general-purpose buttons */
+ {NDOF_BUTTON_1, "NDOF_BUTTON_1", 0, "Button 1", ""},
+ {NDOF_BUTTON_2, "NDOF_BUTTON_2", 0, "Button 2", ""},
+ {NDOF_BUTTON_3, "NDOF_BUTTON_3", 0, "Button 3", ""},
+ {NDOF_BUTTON_4, "NDOF_BUTTON_4", 0, "Button 4", ""},
+ {NDOF_BUTTON_5, "NDOF_BUTTON_5", 0, "Button 5", ""},
+ {NDOF_BUTTON_6, "NDOF_BUTTON_6", 0, "Button 6", ""},
+ {NDOF_BUTTON_7, "NDOF_BUTTON_7", 0, "Button 7", ""},
+ {NDOF_BUTTON_8, "NDOF_BUTTON_8", 0, "Button 8", ""},
+ {NDOF_BUTTON_9, "NDOF_BUTTON_9", 0, "Button 9", ""},
+ {NDOF_BUTTON_10, "NDOF_BUTTON_10", 0, "Button 10", ""},
{0, NULL, 0, NULL, NULL}};
EnumPropertyItem keymap_propvalue_items[] = {
@@ -303,6 +381,7 @@ EnumPropertyItem wm_report_items[] = {
#define KMI_TYPE_TWEAK 2
#define KMI_TYPE_TEXTINPUT 3
#define KMI_TYPE_TIMER 4
+#define KMI_TYPE_NDOF 5
#ifdef RNA_RUNTIME
@@ -433,6 +512,7 @@ static int rna_wmKeyMapItem_map_type_get(PointerRNA *ptr)
if(ISKEYBOARD(kmi->type)) return KMI_TYPE_KEYBOARD;
if(ISTWEAK(kmi->type)) return KMI_TYPE_TWEAK;
if(ISMOUSE(kmi->type)) return KMI_TYPE_MOUSE;
+ if(ISNDOF(kmi->type)) return KMI_TYPE_NDOF;
if(kmi->type == KM_TEXTINPUT) return KMI_TYPE_TEXTINPUT;
return KMI_TYPE_KEYBOARD;
}
@@ -464,6 +544,10 @@ static void rna_wmKeyMapItem_map_type_set(PointerRNA *ptr, int value)
kmi->type= TIMER;
kmi->val= KM_NOTHING;
break;
+ case KMI_TYPE_NDOF:
+ kmi->type = NDOF_BUTTON_MENU;
+ kmi->val = KM_NOTHING;
+ break;
}
}
}
@@ -475,6 +559,7 @@ static EnumPropertyItem *rna_KeyMapItem_type_itemf(bContext *UNUSED(C), PointerR
if(map_type == KMI_TYPE_MOUSE) return event_mouse_type_items;
if(map_type == KMI_TYPE_TWEAK) return event_tweak_type_items;
if(map_type == KMI_TYPE_TIMER) return event_timer_type_items;
+ if(map_type == KMI_TYPE_NDOF) return event_ndof_type_items;
else return event_type_items;
}
@@ -482,7 +567,7 @@ static EnumPropertyItem *rna_KeyMapItem_value_itemf(bContext *UNUSED(C), Pointer
{
int map_type= rna_wmKeyMapItem_map_type_get(ptr);
- if(map_type == KMI_TYPE_MOUSE || map_type == KMI_TYPE_KEYBOARD) return event_keymouse_value_items;
+ if(map_type == KMI_TYPE_MOUSE || map_type == KMI_TYPE_KEYBOARD || map_type == KMI_TYPE_NDOF) return event_keymouse_value_items;
if(map_type == KMI_TYPE_TWEAK) return event_tweak_value_items;
else return event_value_items;
}
@@ -940,7 +1025,7 @@ static StructRNA *rna_Operator_register(Main *bmain, ReportList *reports, void *
rna_Operator_unregister(bmain, ot->ext.srna);
}
- /* create a new menu type */
+ /* create a new operator type */
dummyot.ext.srna= RNA_def_struct(&BLENDER_RNA, dummyot.idname, "Operator");
RNA_def_struct_flag(dummyot.ext.srna, STRUCT_NO_IDPROPERTIES); /* operator properties are registered separately */
dummyot.ext.data= data;
@@ -1653,6 +1738,7 @@ static void rna_def_keyconfig(BlenderRNA *brna)
{KMI_TYPE_KEYBOARD, "KEYBOARD", 0, "Keyboard", ""},
{KMI_TYPE_TWEAK, "TWEAK", 0, "Tweak", ""},
{KMI_TYPE_MOUSE, "MOUSE", 0, "Mouse", ""},
+ {KMI_TYPE_NDOF, "NDOF", 0, "NDOF", ""},
{KMI_TYPE_TEXTINPUT, "TEXTINPUT", 0, "Text Input", ""},
{KMI_TYPE_TIMER, "TIMER", 0, "Timer", ""},
{0, NULL, 0, NULL, NULL}};
diff --git a/source/blender/makesrna/intern/rna_wm_api.c b/source/blender/makesrna/intern/rna_wm_api.c
index e250cc84aa3..d44b68950f7 100644
--- a/source/blender/makesrna/intern/rna_wm_api.c
+++ b/source/blender/makesrna/intern/rna_wm_api.c
@@ -205,7 +205,7 @@ void RNA_api_operator(StructRNA *srna)
/* check */
func= RNA_def_function(srna, "check", NULL);
- RNA_def_function_ui_description(func, "Check the operator settings.");
+ RNA_def_function_ui_description(func, "Check the operator settings, return True to signal a change to redraw.");
RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL);
parm= RNA_def_pointer(func, "context", "Context", "", "");
RNA_def_property_flag(parm, PROP_REQUIRED|PROP_NEVER_NULL);
diff --git a/source/blender/modifiers/intern/MOD_uvproject.c b/source/blender/modifiers/intern/MOD_uvproject.c
index a5d2e0b38c7..922ae8c1e92 100644
--- a/source/blender/modifiers/intern/MOD_uvproject.c
+++ b/source/blender/modifiers/intern/MOD_uvproject.c
@@ -42,6 +42,7 @@
#include "DNA_object_types.h"
#include "BLI_math.h"
+#include "BLI_string.h"
#include "BLI_uvproject.h"
#include "BLI_utildefines.h"
@@ -83,6 +84,7 @@ static void copyData(ModifierData *md, ModifierData *target)
tumd->aspecty = umd->aspecty;
tumd->scalex = umd->scalex;
tumd->scaley = umd->scaley;
+ BLI_strncpy(tumd->uvlayer_name, umd->uvlayer_name, sizeof(umd->uvlayer_name));
}
static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *UNUSED(md))
diff --git a/source/blender/python/intern/bpy_props.c b/source/blender/python/intern/bpy_props.c
index 0ba80bf0850..a0ad1ff7850 100644
--- a/source/blender/python/intern/bpy_props.c
+++ b/source/blender/python/intern/bpy_props.c
@@ -326,6 +326,11 @@ static int bpy_prop_callback_assign(struct PropertyRNA *prop, PyObject *update_c
" :type description: string\n" \
+#define BPY_PROPDEF_UNIT_DOC \
+" :arg unit: Enumerator in ['NONE', 'LENGTH', 'AREA', 'VOLUME', 'ROTATION', 'TIME', 'VELOCITY', 'ACCELERATION'].\n" \
+" :type unit: 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" \
@@ -639,8 +644,7 @@ BPY_PROPDEF_DESC_DOC
" :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_UNIT_DOC
BPY_PROPDEF_UPDATE_DOC
);
static PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw)
@@ -679,7 +683,7 @@ static PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw)
BPY_PROPDEF_SUBTYPE_CHECK(FloatProperty, property_flag_items, property_subtype_number_items)
if(pyunit && RNA_enum_value_from_id(property_unit_items, pyunit, &unit)==0) {
- PyErr_Format(PyExc_TypeError, "FloatProperty(unit='%s'): invalid unit");
+ PyErr_Format(PyExc_TypeError, "FloatProperty(unit='%s'): invalid unit", pyunit);
return NULL;
}
@@ -716,6 +720,7 @@ BPY_PROPDEF_DESC_DOC
" :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"
+BPY_PROPDEF_UNIT_DOC
" :arg size: Vector dimensions in [1, and " STRINGIFY(PYRNA_STACK_ARRAY) "].\n"
" :type size: int\n"
BPY_PROPDEF_UPDATE_DOC
@@ -727,7 +732,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", "update", NULL};
+ static const char *kwlist[]= {"attr", "name", "description", "default", "min", "max", "soft_min", "soft_max", "step", "precision", "options", "subtype", "unit", "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};
@@ -738,15 +743,17 @@ static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObjec
int opts=0;
char *pysubtype= NULL;
int subtype= PROP_NONE;
+ char *pyunit= NULL;
+ int unit= PROP_UNIT_NONE;
PyObject *update_cb= NULL;
if (!PyArg_ParseTupleAndKeywords(args, kw,
- "s#|ssOfffffiO!siO:FloatVectorProperty",
+ "s#|ssOfffffiO!ssiO:FloatVectorProperty",
(char **)kwlist, &id, &id_len,
&name, &description, &pydef,
&min, &max, &soft_min, &soft_max,
&step, &precision, &PySet_Type,
- &pyopts, &pysubtype, &size,
+ &pyopts, &pysubtype, &pyunit, &size,
&update_cb))
{
return NULL;
@@ -754,6 +761,11 @@ static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObjec
BPY_PROPDEF_SUBTYPE_CHECK(FloatVectorProperty, property_flag_items, property_subtype_array_items)
+ if(pyunit && RNA_enum_value_from_id(property_unit_items, pyunit, &unit)==0) {
+ PyErr_Format(PyExc_TypeError, "FloatVectorProperty(unit='%s'): invalid unit", pyunit);
+ return NULL;
+ }
+
if(size < 1 || size > PYRNA_STACK_ARRAY) {
PyErr_Format(PyExc_TypeError, "FloatVectorProperty(size=%d): size must be between 0 and " STRINGIFY(PYRNA_STACK_ARRAY), size);
return NULL;
@@ -766,7 +778,7 @@ static PyObject *BPy_FloatVectorProperty(PyObject *self, PyObject *args, PyObjec
return NULL;
}
- prop= RNA_def_property(srna, id, PROP_FLOAT, subtype);
+ prop= RNA_def_property(srna, id, PROP_FLOAT, subtype | unit);
RNA_def_property_array(prop, size);
if(pydef) RNA_def_property_float_array_default(prop, def);
RNA_def_property_range(prop, min, max);
diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c
index 6e1b9c807f3..502b25842de 100644
--- a/source/blender/python/intern/bpy_rna.c
+++ b/source/blender/python/intern/bpy_rna.c
@@ -3262,11 +3262,15 @@ static PyObject *pyrna_prop_dir(BPy_PropertyRNA *self)
* */
ret= PyList_New(0);
- if (!BPy_PropertyRNA_CheckExact(self))
+ if (!BPy_PropertyRNA_CheckExact(self)) {
pyrna_dir_members_py(ret, (PyObject *)self);
+ }
- if(RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr))
- pyrna_dir_members_rna(ret, &r_ptr);
+ if(RNA_property_type(self->prop) == PROP_COLLECTION) {
+ if(RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr)) {
+ pyrna_dir_members_rna(ret, &r_ptr);
+ }
+ }
return ret;
}
@@ -6407,7 +6411,9 @@ PyDoc_STRVAR(pyrna_register_class_doc,
" If the class has a *register* class method it will be called\n"
" before registration.\n"
"\n"
-" .. note:: :exc:`ValueError` exception is raised if the class is not a\n"
+" .. note::\n"
+"\n"
+" :exc:`ValueError` exception is raised if the class is not a\n"
" subclass of a registerable blender class.\n"
"\n"
);
diff --git a/source/blender/python/mathutils/mathutils.h b/source/blender/python/mathutils/mathutils.h
index 7454cfe78b3..b798b5e7003 100644
--- a/source/blender/python/mathutils/mathutils.h
+++ b/source/blender/python/mathutils/mathutils.h
@@ -108,4 +108,6 @@ int _BaseMathObject_WriteIndexCallback(BaseMathObject *self, int index);
int mathutils_array_parse(float *array, int array_min, int array_max, PyObject *value, const char *error_prefix);
int mathutils_any_to_rotmat(float rmat[3][3], PyObject *value, const char *error_prefix);
+int column_vector_multiplication(float rvec[4], VectorObject *vec, MatrixObject *mat);
+
#endif /* MATHUTILS_H */
diff --git a/source/blender/python/mathutils/mathutils_Matrix.c b/source/blender/python/mathutils/mathutils_Matrix.c
index 76a0994c3aa..3953171f263 100644
--- a/source/blender/python/mathutils/mathutils_Matrix.c
+++ b/source/blender/python/mathutils/mathutils_Matrix.c
@@ -1612,8 +1612,20 @@ static PyObject *Matrix_mul(PyObject *m1, PyObject *m2)
}
}
else if(mat1) {
+ /*VEC * MATRIX */
+ if(VectorObject_Check(m2)) {
+ VectorObject *vec2= (VectorObject *)m2;
+ float tvec[4];
+ if(BaseMath_ReadCallback(vec2) == -1)
+ return NULL;
+ if(column_vector_multiplication(tvec, vec2, mat1) == -1) {
+ return NULL;
+ }
+
+ return newVectorObject(tvec, vec2->size, Py_NEW, Py_TYPE(m2));
+ }
/*FLOAT/INT * MATRIX */
- if (((scalar= PyFloat_AsDouble(m2)) == -1.0f && PyErr_Occurred())==0) {
+ else if (((scalar= PyFloat_AsDouble(m2)) == -1.0f && PyErr_Occurred())==0) {
return matrix_mul_float(mat1, scalar);
}
}
diff --git a/source/blender/python/mathutils/mathutils_Quaternion.c b/source/blender/python/mathutils/mathutils_Quaternion.c
index 3b05b9a250b..2be258a1ef0 100644
--- a/source/blender/python/mathutils/mathutils_Quaternion.c
+++ b/source/blender/python/mathutils/mathutils_Quaternion.c
@@ -753,8 +753,30 @@ static PyObject *Quaternion_mul(PyObject *q1, PyObject *q2)
return quat_mul_float(quat2, scalar);
}
}
- else if (quat1) { /* QUAT*FLOAT */
- if((((scalar= PyFloat_AsDouble(q2)) == -1.0f && PyErr_Occurred())==0)) {
+ else if (quat1) {
+ /* QUAT * VEC */
+ if (VectorObject_Check(q2)) {
+ VectorObject *vec2 = (VectorObject *)q2;
+ float tvec[3];
+
+ if(vec2->size != 3) {
+ PyErr_SetString(PyExc_ValueError,
+ "Vector multiplication: "
+ "only 3D vector rotations (with quats) "
+ "currently supported");
+ return NULL;
+ }
+ if(BaseMath_ReadCallback(vec2) == -1) {
+ return NULL;
+ }
+
+ copy_v3_v3(tvec, vec2->vec);
+ mul_qt_v3(quat1->quat, tvec);
+
+ return newVectorObject(tvec, 3, Py_NEW, Py_TYPE(vec2));
+ }
+ /* QUAT * FLOAT */
+ else if((((scalar= PyFloat_AsDouble(q2)) == -1.0f && PyErr_Occurred())==0)) {
return quat_mul_float(quat1, scalar);
}
}
diff --git a/source/blender/python/mathutils/mathutils_Vector.c b/source/blender/python/mathutils/mathutils_Vector.c
index e2c958adaa5..a954c07c98d 100644
--- a/source/blender/python/mathutils/mathutils_Vector.c
+++ b/source/blender/python/mathutils/mathutils_Vector.c
@@ -37,6 +37,8 @@
#include "BLI_math.h"
#include "BLI_utildefines.h"
+extern void PyC_LineSpit(void);
+
#define MAX_DIMENSIONS 4
/* Swizzle axes get packed into a single value that is used as a closure. Each
@@ -1081,7 +1083,7 @@ static PyObject *Vector_isub(PyObject *v1, PyObject *v2)
* note: vector/matrix multiplication IS NOT COMMUTATIVE!!!!
* note: assume read callbacks have been done first.
*/
-static int column_vector_multiplication(float rvec[MAX_DIMENSIONS], VectorObject* vec, MatrixObject * mat)
+int column_vector_multiplication(float rvec[MAX_DIMENSIONS], VectorObject* vec, MatrixObject * mat)
{
float vec_cpy[MAX_DIMENSIONS];
double dot = 0.0f;
@@ -1159,8 +1161,29 @@ static PyObject *Vector_mul(PyObject *v1, PyObject *v2)
}
else if (vec1) {
if (MatrixObject_Check(v2)) {
+ extern void PyC_LineSpit(void);
+
/* VEC * MATRIX */
+ /* this is deprecated!, use the reverse instead */
float tvec[MAX_DIMENSIONS];
+
+
+/* ------ to be removed ------*/
+#ifndef MATH_STANDALONE
+#ifdef WITH_ASSERT_ABORT
+ PyErr_SetString(PyExc_ValueError,
+ "(Vector * Matrix) is now removed, reverse the "
+ "order (promoted to an Error for Debug builds)");
+ return NULL;
+#else
+ printf("Warning: (Vector * Matrix) is now deprecated, "
+ "reverse the multiplication order in the script.\n");
+ PyC_LineSpit();
+#endif
+#endif /* ifndef MATH_STANDALONE */
+/* ------ to be removed ------*/
+
+
if(BaseMath_ReadCallback((MatrixObject *)v2) == -1)
return NULL;
if(column_vector_multiplication(tvec, vec1, (MatrixObject*)v2) == -1) {
@@ -1183,6 +1206,24 @@ static PyObject *Vector_mul(PyObject *v1, PyObject *v2)
if(BaseMath_ReadCallback(quat2) == -1) {
return NULL;
}
+
+
+/* ------ to be removed ------*/
+#ifndef MATH_STANDALONE
+#ifdef WITH_ASSERT_ABORT
+ PyErr_SetString(PyExc_ValueError,
+ "(Vector * Quat) is now removed, reverse the "
+ "order (promoted to an Error for Debug builds)");
+ return NULL;
+#else
+ printf("Warning: (Vector * Quat) is now deprecated, "
+ "reverse the multiplication order in the script.\n");
+ PyC_LineSpit();
+#endif
+#endif /* ifndef MATH_STANDALONE */
+/* ------ to be removed ------*/
+
+
copy_v3_v3(tvec, vec1->vec);
mul_qt_v3(quat2->quat, tvec);
return newVectorObject(tvec, 3, Py_NEW, Py_TYPE(vec1));
@@ -1226,6 +1267,24 @@ static PyObject *Vector_imul(PyObject *v1, PyObject *v2)
if(column_vector_multiplication(rvec, vec, (MatrixObject*)v2) == -1)
return NULL;
+
+/* ------ to be removed ------*/
+#ifndef MATH_STANDALONE
+#ifdef WITH_ASSERT_ABORT
+ PyErr_SetString(PyExc_ValueError,
+ "(Vector *= Matrix) is now removed, reverse the "
+ "order (promoted to an Error for Debug builds) "
+ "and uses the non in-place multiplication.");
+ return NULL;
+#else
+ printf("Warning: (Vector *= Matrix) is now deprecated, "
+ "reverse the (non in-place) multiplication order in the script.\n");
+ PyC_LineSpit();
+#endif
+#endif /* ifndef MATH_STANDALONE */
+/* ------ to be removed ------*/
+
+
memcpy(vec->vec, rvec, sizeof(float) * vec->size);
}
else if (QuaternionObject_Check(v2)) {
@@ -1242,6 +1301,25 @@ static PyObject *Vector_imul(PyObject *v1, PyObject *v2)
if(BaseMath_ReadCallback(quat2) == -1) {
return NULL;
}
+
+
+/* ------ to be removed ------*/
+#ifndef MATH_STANDALONE
+#ifdef WITH_ASSERT_ABORT
+ PyErr_SetString(PyExc_ValueError,
+ "(Vector *= Quat) is now removed, reverse the "
+ "order (promoted to an Error for Debug builds) "
+ "and uses the non in-place multiplication.");
+ return NULL;
+#else
+ printf("Warning: (Vector *= Quat) is now deprecated, "
+ "reverse the (non in-place) multiplication order in the script.\n");
+ PyC_LineSpit();
+#endif
+#endif /* ifndef MATH_STANDALONE */
+/* ------ to be removed ------*/
+
+
mul_qt_v3(quat2->quat, vec->vec);
}
else if (((scalar= PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred())==0) { /* VEC *= FLOAT */
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
index 7782077604d..b385b507707 100644
--- a/source/blender/render/intern/source/convertblender.c
+++ b/source/blender/render/intern/source/convertblender.c
@@ -5778,6 +5778,14 @@ void RE_Database_Baking(Render *re, Main *bmain, Scene *scene, unsigned int lay,
if(re->r.mode & R_RAYTRACE)
makeraytree(re);
+ /* point density texture */
+ if(!re->test_break(re->tbh))
+ make_pointdensities(re);
+
+ /* voxel data texture */
+ if(!re->test_break(re->tbh))
+ make_voxeldata(re);
+
/* occlusion */
if((re->wrld.mode & (WO_AMB_OCC|WO_ENV_LIGHT|WO_INDIRECT_LIGHT)) && !re->test_break(re->tbh))
if(re->wrld.ao_gather_method == WO_AOGATHER_APPROX)
diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c
index a7e19c8db4f..c08d6c0f456 100644
--- a/source/blender/render/intern/source/rendercore.c
+++ b/source/blender/render/intern/source/rendercore.c
@@ -730,7 +730,7 @@ static void atm_tile(RenderPart *pa, RenderLayer *rl)
if(zpass==NULL) return;
- /* check for at least one sun lamp that its atmosphere flag is is enabled */
+ /* check for at least one sun lamp that its atmosphere flag is enabled */
for(go=R.lights.first; go; go= go->next) {
lar= go->lampren;
if(lar->type==LA_SUN && lar->sunsky && (lar->sunsky->effect_type & LA_SUN_EFFECT_AP))
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index 67294a8eb53..e6325e2101a 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -272,6 +272,7 @@ void WM_operator_py_idname(char *to, const char *from);
/* *************** menu types ******************** */
struct MenuType *WM_menutype_find(const char *idname, int quiet);
int WM_menutype_add(struct MenuType* mt);
+int WM_menutype_contains(struct MenuType* mt);
void WM_menutype_freelink(struct MenuType* mt);
void WM_menutype_free(void);
diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h
index 49bd3ede37d..7fd52e89a5f 100644
--- a/source/blender/windowmanager/WM_types.h
+++ b/source/blender/windowmanager/WM_types.h
@@ -377,6 +377,26 @@ typedef struct wmTabletData {
float Ytilt; /* as above */
} wmTabletData;
+typedef enum { // motion progress, for modal handlers
+ P_NOT_STARTED,
+ P_STARTING, // <--
+ P_IN_PROGRESS, // <-- only these are sent for NDOF motion
+ P_FINISHING, // <--
+ P_FINISHED
+ } wmProgress;
+
+typedef struct wmNDOFMotionData {
+ /* awfully similar to GHOST_TEventNDOFMotionData... */
+ // Each component normally ranges from -1 to +1, but can exceed that.
+ // These use blender standard view coordinates, with positive rotations being CCW about the axis.
+ float tvec[3]; // translation
+ float rvec[3]; // rotation:
+ // axis = (rx,ry,rz).normalized
+ // amount = (rx,ry,rz).magnitude [in revolutions, 1.0 = 360 deg]
+ float dt; // time since previous NDOF Motion event
+ wmProgress progress; // is this the first event, the last, or one of many in between?
+} wmNDOFMotionData;
+
typedef struct wmTimer {
struct wmTimer *next, *prev;
diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c
index bcd5cf38f88..a535c0bc1f8 100644
--- a/source/blender/windowmanager/intern/wm.c
+++ b/source/blender/windowmanager/intern/wm.c
@@ -175,6 +175,12 @@ int WM_menutype_add(MenuType* mt)
return 1;
}
+/* inefficient but only used for tooltip code */
+int WM_menutype_contains(MenuType* mt)
+{
+ return (mt != NULL && BLI_findindex(&menutypes, mt) != -1);
+}
+
void WM_menutype_freelink(MenuType* mt)
{
BLI_freelinkN(&menutypes, mt);
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index ce3830b059c..2f0c1a72be9 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -1815,7 +1815,10 @@ void wm_event_do_handlers(bContext *C)
/* for regions having custom cursors */
wm_paintcursor_test(C, event);
}
-
+ else if (event->type==NDOF_MOTION) {
+ win->addmousemove = TRUE;
+ }
+
for(sa= win->screen->areabase.first; sa; sa= sa->next) {
if(wm_event_inside_i(event, &sa->totrct)) {
CTX_wm_area_set(C, sa);
@@ -1879,7 +1882,10 @@ void wm_event_do_handlers(bContext *C)
if(doit && win->screen && win->screen->subwinactive != win->screen->mainwin) {
win->eventstate->prevx= event->x;
win->eventstate->prevy= event->y;
+ //printf("win->eventstate->prev = %d %d\n", event->x, event->y);
}
+ else
+ ;//printf("not setting prev to %d %d\n", event->x, event->y);
}
/* store last event for this window */
@@ -1922,6 +1928,7 @@ void wm_event_do_handlers(bContext *C)
/* only add mousemove when queue was read entirely */
if(win->addmousemove && win->eventstate) {
wmEvent tevent= *(win->eventstate);
+ //printf("adding MOUSEMOVE %d %d\n", tevent.x, tevent.y);
tevent.type= MOUSEMOVE;
tevent.prevx= tevent.x;
tevent.prevy= tevent.y;
@@ -2309,6 +2316,45 @@ static void update_tablet_data(wmWindow *win, wmEvent *event)
}
}
+/* adds customdata to event */
+static void attach_ndof_data(wmEvent* event, const GHOST_TEventNDOFMotionData* ghost)
+{
+ wmNDOFMotionData* data = MEM_mallocN(sizeof(wmNDOFMotionData), "customdata NDOF");
+
+ const float s = U.ndof_sensitivity;
+
+ data->tvec[0]= s * ghost->tx;
+ data->rvec[0]= s * ghost->rx;
+
+ if (U.ndof_flag & NDOF_ZOOM_UPDOWN)
+ {
+ // swap Y and Z
+ data->tvec[1]= s * ghost->tz;
+ data->tvec[2]= s * ghost->ty;
+
+ // should this affect rotation also?
+ // initial guess is 'yes', but get user feedback immediately!
+ data->rvec[1]= s * ghost->rz;
+ data->rvec[2]= s * ghost->ry;
+ }
+ else
+ {
+ data->tvec[1]= s * ghost->ty;
+ data->tvec[2]= s * ghost->tz;
+
+ data->rvec[1]= s * ghost->ry;
+ data->rvec[2]= s * ghost->rz;
+ }
+
+ data->dt = ghost->dt;
+
+ data->progress = (wmProgress) ghost->progress;
+
+ event->custom = EVT_DATA_NDOF_MOTION;
+ event->customdata = data;
+ event->customdatafree = 1;
+}
+
/* imperfect but probably usable... draw/enable drags to other windows */
static wmWindow *wm_event_cursor_other_windows(wmWindowManager *wm, wmWindow *win, wmEvent *evt)
{
@@ -2355,7 +2401,7 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U
{
wmWindow *owin;
wmEvent event, *evt= win->eventstate;
-
+
/* initialize and copy state (only mouse x y and modifiers) */
event= *evt;
@@ -2384,6 +2430,8 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U
update_tablet_data(win, &event);
wm_event_add(win, &event);
+
+ //printf("sending MOUSEMOVE %d %d\n", event.x, event.y);
/* also add to other window if event is there, this makes overdraws disappear nicely */
/* it remaps mousecoord to other window in event */
@@ -2557,6 +2605,38 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U
break;
}
+ case GHOST_kEventNDOFMotion: {
+ event.type = NDOF_MOTION;
+ attach_ndof_data(&event, customdata);
+ wm_event_add(win, &event);
+
+ //printf("sending NDOF_MOTION, prev = %d %d\n", event.x, event.y);
+
+ break;
+ }
+
+ case GHOST_kEventNDOFButton: {
+ GHOST_TEventNDOFButtonData* e = customdata;
+
+ event.type = NDOF_BUTTON_NONE + e->button;
+
+ switch (e->action) {
+ case GHOST_kPress:
+ event.val = KM_PRESS;
+ break;
+ case GHOST_kRelease:
+ event.val = KM_RELEASE;
+ break;
+ }
+
+ event.custom = 0;
+ event.customdata = NULL;
+
+ wm_event_add(win, &event);
+
+ break;
+ }
+
case GHOST_kEventUnknown:
case GHOST_kNumEventTypes:
break;
diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c
index ed28696ef69..e22829577f4 100644
--- a/source/blender/windowmanager/intern/wm_init_exit.c
+++ b/source/blender/windowmanager/intern/wm_init_exit.c
@@ -155,7 +155,8 @@ void WM_init(bContext *C, int argc, const char **argv)
BPY_python_start(argc, argv);
BPY_driver_reset();
- BPY_app_handlers_reset();
+ BPY_app_handlers_reset(); /* causes addon callbacks to be freed [#28068],
+ * but this is actually what we want. */
BPY_modules_load_user(C);
#else
(void)argc; /* unused */
@@ -182,8 +183,6 @@ void WM_init(bContext *C, int argc, const char **argv)
ED_preview_init_dbase();
- G.ndofdevice = -1; /* XXX bad initializer, needs set otherwise buttons show! */
-
WM_read_history();
/* allow a path of "", this is what happens when making a new file */
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index 29afdb570ea..a47dfacf358 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -3416,7 +3416,49 @@ static void WM_OT_memory_statistics(wmOperatorType *ot)
}
/* ******************************************************* */
-
+
+static int wm_ndof_sensitivity_exec(bContext *UNUSED(C), wmOperator *op)
+{
+ const float min = 0.25f, max = 4.f; // TODO: get these from RNA property
+ float change;
+ float sensitivity = U.ndof_sensitivity;
+
+ if(RNA_boolean_get(op->ptr, "fast"))
+ change = 0.5f; // 50% change
+ else
+ change = 0.1f; // 10%
+
+ if(RNA_boolean_get(op->ptr, "decrease")) {
+ sensitivity -= sensitivity * change;
+ if (sensitivity < min)
+ sensitivity = min;
+ }
+ else {
+ sensitivity += sensitivity * change;
+ if (sensitivity > max)
+ sensitivity = max;
+ }
+
+ if (sensitivity != U.ndof_sensitivity) {
+ U.ndof_sensitivity = sensitivity;
+ }
+
+ return OPERATOR_FINISHED;
+}
+
+static void WM_OT_ndof_sensitivity_change(wmOperatorType *ot)
+{
+ ot->name= "Change NDOF sensitivity";
+ ot->idname= "WM_OT_ndof_sensitivity_change";
+ ot->description="Change NDOF sensitivity";
+
+ ot->exec= wm_ndof_sensitivity_exec;
+
+ RNA_def_boolean(ot->srna, "decrease", 1, "Decrease NDOF sensitivity", "If true then action decreases NDOF sensitivity instead of increasing");
+ RNA_def_boolean(ot->srna, "fast", 0, "Fast NDOF sensitivity change", "If true then sensitivity changes 50%, otherwise 10%");
+}
+
+/* ******************************************************* */
/* called on initialize WM_exit() */
void wm_operatortype_free(void)
{
@@ -3455,6 +3497,7 @@ void wm_operatortype_init(void)
WM_operatortype_append(WM_OT_search_menu);
WM_operatortype_append(WM_OT_call_menu);
WM_operatortype_append(WM_OT_radial_control);
+ WM_operatortype_append(WM_OT_ndof_sensitivity_change);
#if defined(WIN32)
WM_operatortype_append(WM_OT_console_toggle);
#endif
@@ -3674,11 +3717,12 @@ void wm_window_keymap(wmKeyConfig *keyconf)
/* debug/testing */
WM_keymap_verify_item(keymap, "WM_OT_redraw_timer", TKEY, KM_PRESS, KM_ALT|KM_CTRL, 0);
WM_keymap_verify_item(keymap, "WM_OT_debug_menu", DKEY, KM_PRESS, KM_ALT|KM_CTRL, 0);
- WM_keymap_verify_item(keymap, "WM_OT_search_menu", SPACEKEY, KM_PRESS, 0, 0);
-
- /* Space switching */
+ /* menus that can be accessed anywhere in blender */
+ WM_keymap_verify_item(keymap, "WM_OT_search_menu", SPACEKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_menu(keymap, "VIEW3D_MT_ndof_settings", NDOF_BUTTON_MENU, KM_PRESS, 0, 0);
+ /* Space switching */
kmi = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", F2KEY, KM_PRESS, KM_SHIFT, 0); /* new in 2.5x, was DXF export */
RNA_string_set(kmi->ptr, "data_path", "area.type");
RNA_string_set(kmi->ptr, "value", "LOGIC_EDITOR");
@@ -3722,6 +3766,23 @@ void wm_window_keymap(wmKeyConfig *keyconf)
kmi = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", F12KEY, KM_PRESS, KM_SHIFT, 0);
RNA_string_set(kmi->ptr, "data_path", "area.type");
RNA_string_set(kmi->ptr, "value", "DOPESHEET_EDITOR");
+
+ /* ndof speed */
+ kmi= WM_keymap_add_item(keymap, "WM_OT_ndof_sensitivity_change", NDOF_BUTTON_PLUS, KM_PRESS, 0, 0);
+ RNA_boolean_set(kmi->ptr, "decrease", FALSE);
+ RNA_boolean_set(kmi->ptr, "fast", FALSE);
+
+ kmi= WM_keymap_add_item(keymap, "WM_OT_ndof_sensitivity_change", NDOF_BUTTON_MINUS, KM_PRESS, 0, 0);
+ RNA_boolean_set(kmi->ptr, "decrease", TRUE);
+ RNA_boolean_set(kmi->ptr, "fast", FALSE);
+
+ kmi= WM_keymap_add_item(keymap, "WM_OT_ndof_sensitivity_change", NDOF_BUTTON_PLUS, KM_PRESS, KM_SHIFT, 0);
+ RNA_boolean_set(kmi->ptr, "decrease", FALSE);
+ RNA_boolean_set(kmi->ptr, "fast", TRUE);
+
+ kmi= WM_keymap_add_item(keymap, "WM_OT_ndof_sensitivity_change", NDOF_BUTTON_MINUS, KM_PRESS, KM_SHIFT, 0);
+ RNA_boolean_set(kmi->ptr, "decrease", TRUE);
+ RNA_boolean_set(kmi->ptr, "fast", TRUE);
gesture_circle_modal_keymap(keyconf);
gesture_border_modal_keymap(keyconf);
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
index 9b1695be67a..7d6010786d2 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -621,12 +621,12 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr private)
if (!ghostwin) {
// XXX - should be checked, why are we getting an event here, and
// what is it?
-
+ puts("<!> event has no window");
return 1;
} else if (!GHOST_ValidWindow(g_system, ghostwin)) {
// XXX - should be checked, why are we getting an event here, and
// what is it?
-
+ puts("<!> event has invalid window");
return 1;
} else {
win= GHOST_GetWindowUserData(ghostwin);
diff --git a/source/blender/windowmanager/wm_event_types.h b/source/blender/windowmanager/wm_event_types.h
index ee080e7c0aa..579f20ca605 100644
--- a/source/blender/windowmanager/wm_event_types.h
+++ b/source/blender/windowmanager/wm_event_types.h
@@ -45,6 +45,7 @@
#define EVT_DATA_GESTURE 2
#define EVT_DATA_TIMER 3
#define EVT_DATA_LISTBASE 4
+#define EVT_DATA_NDOF_MOTION 5
/* tablet active, matches GHOST_TTabletMode */
#define EVT_TABLET_NONE 0
@@ -78,6 +79,56 @@
#define INBETWEEN_MOUSEMOVE 17
+/* NDOF (from SpaceNavigator & friends)
+ These should be kept in sync with GHOST_NDOFManager.h
+ Ordering matters, exact values do not. */
+
+#define NDOF_MOTION 400
+
+enum {
+ // used internally, never sent
+ NDOF_BUTTON_NONE = NDOF_MOTION,
+ // these two are available from any 3Dconnexion device
+ NDOF_BUTTON_MENU,
+ NDOF_BUTTON_FIT,
+ // standard views
+ NDOF_BUTTON_TOP,
+ NDOF_BUTTON_BOTTOM,
+ NDOF_BUTTON_LEFT,
+ NDOF_BUTTON_RIGHT,
+ NDOF_BUTTON_FRONT,
+ NDOF_BUTTON_BACK,
+ // more views
+ NDOF_BUTTON_ISO1,
+ NDOF_BUTTON_ISO2,
+ // 90 degree rotations
+ NDOF_BUTTON_ROLL_CW,
+ NDOF_BUTTON_ROLL_CCW,
+ NDOF_BUTTON_SPIN_CW,
+ NDOF_BUTTON_SPIN_CCW,
+ NDOF_BUTTON_TILT_CW,
+ NDOF_BUTTON_TILT_CCW,
+ // device control
+ NDOF_BUTTON_ROTATE,
+ NDOF_BUTTON_PANZOOM,
+ NDOF_BUTTON_DOMINANT,
+ NDOF_BUTTON_PLUS,
+ NDOF_BUTTON_MINUS,
+ // general-purpose buttons
+ NDOF_BUTTON_1,
+ NDOF_BUTTON_2,
+ NDOF_BUTTON_3,
+ NDOF_BUTTON_4,
+ NDOF_BUTTON_5,
+ NDOF_BUTTON_6,
+ NDOF_BUTTON_7,
+ NDOF_BUTTON_8,
+ NDOF_BUTTON_9,
+ NDOF_BUTTON_10,
+ NDOF_LAST
+ };
+
+
/* SYSTEM : 0x01xx */
#define INPUTCHANGE 0x0103 /* input connected or disconnected */
#define WINDEACTIVATE 0x0104 /* window is deactivated, focus lost */
@@ -240,8 +291,11 @@
/* test whether the event is tweak event */
#define ISTWEAK(event) (event >= EVT_TWEAK_L && event <= EVT_GESTURE)
+ /* test whether the event is a NDOF event */
+#define ISNDOF(event) (event >= NDOF_MOTION && event < NDOF_LAST)
+
/* test whether event type is acceptable as hotkey, excluding modifiers */
-#define ISHOTKEY(event) ((ISKEYBOARD(event) || ISMOUSE(event)) && event!=ESCKEY && !(event>=LEFTCTRLKEY && event<=LEFTSHIFTKEY) && !(event>=UNKNOWNKEY && event<=GRLESSKEY))
+#define ISHOTKEY(event) ((ISKEYBOARD(event) || ISMOUSE(event) || ISNDOF(event)) && event!=ESCKEY && !(event>=LEFTCTRLKEY && event<=LEFTSHIFTKEY) && !(event>=UNKNOWNKEY && event<=GRLESSKEY))
/* **************** BLENDER GESTURE EVENTS (0x5000) **************** */
diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c
index 017c74a8edb..87c905c7db6 100644
--- a/source/blenderplayer/bad_level_call_stubs/stubs.c
+++ b/source/blenderplayer/bad_level_call_stubs/stubs.c
@@ -138,7 +138,6 @@ int RE_RenderInProgress(struct Render *re){return 0;}
struct Scene *RE_GetScene(struct Render *re){return (struct Scene *) NULL;}
void RE_Database_Free(struct Render *re){}
void RE_FreeRender(struct Render *re){}
-void RE_shade_external(struct Render *re, struct ShadeInput *shi, struct ShadeResult *shr){}
void RE_DataBase_GetView(struct Render *re, float mat[][4]){}
int externtex(struct MTex *mtex, float *vec, float *tin, float *tr, float *tg, float *tb, float *ta){return 0;}
float texture_value_blend(float tex, float out, float fact, float facg, int blendtype, int flip){return 0.0f;}
diff --git a/source/creator/creator.c b/source/creator/creator.c
index fddd6d286db..36209dbda78 100644
--- a/source/creator/creator.c
+++ b/source/creator/creator.c
@@ -434,9 +434,12 @@ static int playback_mode(int UNUSED(argc), const char **UNUSED(argv), void *UNUS
{
/* not if -b was given first */
if (G.background == 0) {
-
-// XXX playanim(argc, argv); /* not the same argc and argv as before */
+#if 0 /* TODO, bring player back? */
+ playanim(argc, argv); /* not the same argc and argv as before */
+#else
+ fprintf(stderr, "Playback mode not supported in blender 2.5x\n");
exit(0);
+#endif
}
return -2;
diff --git a/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp b/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp
index 0e08f157a6a..48ba09e67d2 100644
--- a/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp
+++ b/source/gameengine/GameLogic/Joystick/SCA_Joystick.cpp
@@ -89,7 +89,7 @@ SCA_Joystick *SCA_Joystick::GetInstance( short int joyindex )
{
int i;
// do this once only
- if(SDL_InitSubSystem(SDL_INIT_JOYSTICK) == -1 ){
+ if(SDL_InitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_VIDEO) == -1 ){
echo("Error-Initializing-SDL: " << SDL_GetError());
return NULL;
}
@@ -124,7 +124,7 @@ void SCA_Joystick::ReleaseInstance()
m_instance[i]= NULL;
}
- SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
+ SDL_QuitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_VIDEO);
#endif
}
}
diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
index ea0b00e52fd..0aa36b4cd5f 100644
--- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
+++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
@@ -1220,7 +1220,7 @@ void KX_KetsjiEngine::RenderFrame(KX_Scene* scene, KX_Camera* cam)
projmat.setValue(m_overrideCamProjMat.getPointer());
cam->SetProjectionMatrix(projmat);
}
- } else if (cam->hasValidProjectionMatrix() && !cam->GetViewport() )
+ } else if (cam->hasValidProjectionMatrix())
{
m_rasterizer->SetProjectionMatrix(cam->GetProjectionMatrix());
} else
diff --git a/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp b/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp
index 12024657149..fde127b7ef5 100644
--- a/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp
+++ b/source/gameengine/Ketsji/KX_PyConstraintBinding.cpp
@@ -38,12 +38,20 @@
#include "KX_PhysicsObjectWrapper.h"
#include "PHY_IPhysicsController.h"
#include "PHY_IVehicle.h"
+#include "PHY_DynamicTypes.h"
#include "MT_Matrix3x3.h"
#include "PyObjectPlus.h"
+#ifdef USE_BULLET
+# include "LinearMath/btIDebugDraw.h"
+#endif
+
#ifdef WITH_PYTHON
+// macro copied from KX_PythonInit.cpp
+#define KX_MACRO_addTypesToDict(dict, name, name2) PyDict_SetItemString(dict, #name, item=PyLong_FromSsize_t(name2)); Py_DECREF(item)
+
// nasty glob variable to connect scripting language
// if there is a better way (without global), please do so!
static PHY_IPhysicsEnvironment* g_CurrentActivePhysicsEnvironment = NULL;
@@ -84,8 +92,8 @@ static char gPyGetAppliedImpulse__doc__[] = "getAppliedImpulse(int constraintId)
static PyObject* gPySetGravity(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+ PyObject* args,
+ PyObject* kwds)
{
float x,y,z;
if (PyArg_ParseTuple(args,"fff",&x,&y,&z))
@@ -101,8 +109,8 @@ static PyObject* gPySetGravity(PyObject* self,
}
static PyObject* gPySetDebugMode(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+ PyObject* args,
+ PyObject* kwds)
{
int mode;
if (PyArg_ParseTuple(args,"i",&mode))
@@ -124,8 +132,8 @@ static PyObject* gPySetDebugMode(PyObject* self,
static PyObject* gPySetNumTimeSubSteps(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+ PyObject* args,
+ PyObject* kwds)
{
int substep;
if (PyArg_ParseTuple(args,"i",&substep))
@@ -143,8 +151,8 @@ static PyObject* gPySetNumTimeSubSteps(PyObject* self,
static PyObject* gPySetNumIterations(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+ PyObject* args,
+ PyObject* kwds)
{
int iter;
if (PyArg_ParseTuple(args,"i",&iter))
@@ -161,10 +169,9 @@ static PyObject* gPySetNumIterations(PyObject* self,
}
-
static PyObject* gPySetDeactivationTime(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+ PyObject* args,
+ PyObject* kwds)
{
float deactive_time;
if (PyArg_ParseTuple(args,"f",&deactive_time))
@@ -182,8 +189,8 @@ static PyObject* gPySetDeactivationTime(PyObject* self,
static PyObject* gPySetDeactivationLinearTreshold(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+ PyObject* args,
+ PyObject* kwds)
{
float linearDeactivationTreshold;
if (PyArg_ParseTuple(args,"f",&linearDeactivationTreshold))
@@ -201,8 +208,8 @@ static PyObject* gPySetDeactivationLinearTreshold(PyObject* self,
static PyObject* gPySetDeactivationAngularTreshold(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+ PyObject* args,
+ PyObject* kwds)
{
float angularDeactivationTreshold;
if (PyArg_ParseTuple(args,"f",&angularDeactivationTreshold))
@@ -219,8 +226,8 @@ static PyObject* gPySetDeactivationAngularTreshold(PyObject* self,
}
static PyObject* gPySetContactBreakingTreshold(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+ PyObject* args,
+ PyObject* kwds)
{
float contactBreakingTreshold;
if (PyArg_ParseTuple(args,"f",&contactBreakingTreshold))
@@ -238,8 +245,8 @@ static PyObject* gPySetContactBreakingTreshold(PyObject* self,
static PyObject* gPySetCcdMode(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+ PyObject* args,
+ PyObject* kwds)
{
float ccdMode;
if (PyArg_ParseTuple(args,"f",&ccdMode))
@@ -256,8 +263,8 @@ static PyObject* gPySetCcdMode(PyObject* self,
}
static PyObject* gPySetSorConstant(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+ PyObject* args,
+ PyObject* kwds)
{
float sor;
if (PyArg_ParseTuple(args,"f",&sor))
@@ -274,8 +281,8 @@ static PyObject* gPySetSorConstant(PyObject* self,
}
static PyObject* gPySetSolverTau(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+ PyObject* args,
+ PyObject* kwds)
{
float tau;
if (PyArg_ParseTuple(args,"f",&tau))
@@ -293,8 +300,8 @@ static PyObject* gPySetSolverTau(PyObject* self,
static PyObject* gPySetSolverDamping(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+ PyObject* args,
+ PyObject* kwds)
{
float damping;
if (PyArg_ParseTuple(args,"f",&damping))
@@ -311,8 +318,8 @@ static PyObject* gPySetSolverDamping(PyObject* self,
}
static PyObject* gPySetLinearAirDamping(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+ PyObject* args,
+ PyObject* kwds)
{
float damping;
if (PyArg_ParseTuple(args,"f",&damping))
@@ -330,8 +337,8 @@ static PyObject* gPySetLinearAirDamping(PyObject* self,
static PyObject* gPySetUseEpa(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+ PyObject* args,
+ PyObject* kwds)
{
int epa;
if (PyArg_ParseTuple(args,"i",&epa))
@@ -347,8 +354,8 @@ static PyObject* gPySetUseEpa(PyObject* self,
Py_RETURN_NONE;
}
static PyObject* gPySetSolverType(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+ PyObject* args,
+ PyObject* kwds)
{
int solverType;
if (PyArg_ParseTuple(args,"i",&solverType))
@@ -367,8 +374,8 @@ static PyObject* gPySetSolverType(PyObject* self,
static PyObject* gPyGetVehicleConstraint(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+ PyObject* args,
+ PyObject* kwds)
{
#if defined(_WIN64)
__int64 constraintid;
@@ -398,9 +405,6 @@ static PyObject* gPyGetVehicleConstraint(PyObject* self,
}
-
-
-
static PyObject* gPyCreateConstraint(PyObject* self,
PyObject* args,
PyObject* kwds)
@@ -425,39 +429,39 @@ static PyObject* gPyCreateConstraint(PyObject* self,
success = PyArg_ParseTuple(args,"lli",&physicsid,&physicsid2,&constrainttype);
#endif
}
- else
- if (len ==6)
+ else if (len == 6)
{
#if defined(_WIN64)
success = PyArg_ParseTuple(args,"LLifff",&physicsid,&physicsid2,&constrainttype,
- &pivotX,&pivotY,&pivotZ);
+ &pivotX,&pivotY,&pivotZ);
#else
success = PyArg_ParseTuple(args,"llifff",&physicsid,&physicsid2,&constrainttype,
- &pivotX,&pivotY,&pivotZ);
+ &pivotX,&pivotY,&pivotZ);
#endif
}
else if (len == 9)
{
#if defined(_WIN64)
success = PyArg_ParseTuple(args,"LLiffffff",&physicsid,&physicsid2,&constrainttype,
- &pivotX,&pivotY,&pivotZ,&axisX,&axisY,&axisZ);
+ &pivotX,&pivotY,&pivotZ,&axisX,&axisY,&axisZ);
#else
success = PyArg_ParseTuple(args,"lliffffff",&physicsid,&physicsid2,&constrainttype,
- &pivotX,&pivotY,&pivotZ,&axisX,&axisY,&axisZ);
+ &pivotX,&pivotY,&pivotZ,&axisX,&axisY,&axisZ);
#endif
-
}
else if (len == 10)
{
#if defined(_WIN64)
success = PyArg_ParseTuple(args,"LLiffffffi",&physicsid,&physicsid2,&constrainttype,
- &pivotX,&pivotY,&pivotZ,&axisX,&axisY,&axisZ,&flag);
+ &pivotX,&pivotY,&pivotZ,&axisX,&axisY,&axisZ,&flag);
#else
success = PyArg_ParseTuple(args,"lliffffffi",&physicsid,&physicsid2,&constrainttype,
- &pivotX,&pivotY,&pivotZ,&axisX,&axisY,&axisZ,&flag);
+ &pivotX,&pivotY,&pivotZ,&axisX,&axisY,&axisZ,&flag);
#endif
}
- else if (len==4)
+
+ /* XXX extrainfo seems to be nothing implemented. right now it works as a pivot with [X,0,0] */
+ else if (len == 4)
{
#if defined(_WIN64)
success = PyArg_ParseTuple(args,"LLii",&physicsid,&physicsid2,&constrainttype,&extrainfo);
@@ -466,7 +470,7 @@ static PyObject* gPyCreateConstraint(PyObject* self,
#endif
pivotX=extrainfo;
}
-
+
if (success)
{
if (PHY_GetActiveEnvironment())
@@ -490,20 +494,18 @@ static PyObject* gPyCreateConstraint(PyObject* self,
MT_Vector3 axis0 = localCFrame.getColumn(0);
MT_Vector3 axis1 = localCFrame.getColumn(1);
MT_Vector3 axis2 = localCFrame.getColumn(2);
-
- constraintid = PHY_GetActiveEnvironment()->createConstraint(physctrl,physctrl2,(enum PHY_ConstraintType)constrainttype,
- pivotX,pivotY,pivotZ,
- (float)axis0.x(),(float)axis0.y(),(float)axis0.z(),
- (float)axis1.x(),(float)axis1.y(),(float)axis1.z(),
- (float)axis2.x(),(float)axis2.y(),(float)axis2.z(),flag);
- } else
- {
+ constraintid = PHY_GetActiveEnvironment()->createConstraint(physctrl,physctrl2,(enum PHY_ConstraintType)constrainttype,
+ pivotX,pivotY,pivotZ,
+ (float)axis0.x(),(float)axis0.y(),(float)axis0.z(),
+ (float)axis1.x(),(float)axis1.y(),(float)axis1.z(),
+ (float)axis2.x(),(float)axis2.y(),(float)axis2.z(),flag);
+ }
+ else {
constraintid = PHY_GetActiveEnvironment()->createConstraint(physctrl,physctrl2,(enum PHY_ConstraintType)constrainttype,pivotX,pivotY,pivotZ,axisX,axisY,axisZ,0);
}
KX_ConstraintWrapper* wrap = new KX_ConstraintWrapper((enum PHY_ConstraintType)constrainttype,constraintid,PHY_GetActiveEnvironment());
-
return wrap->NewProxy(true);
}
@@ -522,8 +524,8 @@ static PyObject* gPyCreateConstraint(PyObject* self,
static PyObject* gPyGetAppliedImpulse(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+ PyObject* args,
+ PyObject* kwds)
{
float appliedImpulse = 0.f;
@@ -549,8 +551,8 @@ static PyObject* gPyGetAppliedImpulse(PyObject* self,
static PyObject* gPyRemoveConstraint(PyObject* self,
- PyObject* args,
- PyObject* kwds)
+ PyObject* args,
+ PyObject* kwds)
{
#if defined(_WIN64)
__int64 constraintid;
@@ -577,7 +579,7 @@ static PyObject* gPyExportBulletFile(PyObject*, PyObject* args)
char* filename;
if (!PyArg_ParseTuple(args,"s:exportBulletFile",&filename))
return NULL;
-
+
if (PHY_GetActiveEnvironment())
{
PHY_GetActiveEnvironment()->exportFile(filename);
@@ -586,62 +588,61 @@ static PyObject* gPyExportBulletFile(PyObject*, PyObject* args)
}
static struct PyMethodDef physicsconstraints_methods[] = {
- {"setGravity",(PyCFunction) gPySetGravity,
- METH_VARARGS, (const char *)gPySetGravity__doc__},
- {"setDebugMode",(PyCFunction) gPySetDebugMode,
- METH_VARARGS, (const char *)gPySetDebugMode__doc__},
-
- /// settings that influence quality of the rigidbody dynamics
- {"setNumIterations",(PyCFunction) gPySetNumIterations,
- METH_VARARGS, (const char *)gPySetNumIterations__doc__},
-
- {"setNumTimeSubSteps",(PyCFunction) gPySetNumTimeSubSteps,
- METH_VARARGS, (const char *)gPySetNumTimeSubSteps__doc__},
-
- {"setDeactivationTime",(PyCFunction) gPySetDeactivationTime,
- METH_VARARGS, (const char *)gPySetDeactivationTime__doc__},
-
- {"setDeactivationLinearTreshold",(PyCFunction) gPySetDeactivationLinearTreshold,
- METH_VARARGS, (const char *)gPySetDeactivationLinearTreshold__doc__},
- {"setDeactivationAngularTreshold",(PyCFunction) gPySetDeactivationAngularTreshold,
- METH_VARARGS, (const char *)gPySetDeactivationAngularTreshold__doc__},
-
- {"setContactBreakingTreshold",(PyCFunction) gPySetContactBreakingTreshold,
- METH_VARARGS, (const char *)gPySetContactBreakingTreshold__doc__},
- {"setCcdMode",(PyCFunction) gPySetCcdMode,
- METH_VARARGS, (const char *)gPySetCcdMode__doc__},
- {"setSorConstant",(PyCFunction) gPySetSorConstant,
- METH_VARARGS, (const char *)gPySetSorConstant__doc__},
- {"setSolverTau",(PyCFunction) gPySetSolverTau,
- METH_VARARGS, (const char *)gPySetSolverTau__doc__},
- {"setSolverDamping",(PyCFunction) gPySetSolverDamping,
- METH_VARARGS, (const char *)gPySetSolverDamping__doc__},
-
- {"setLinearAirDamping",(PyCFunction) gPySetLinearAirDamping,
- METH_VARARGS, (const char *)gPySetLinearAirDamping__doc__},
-
- {"setUseEpa",(PyCFunction) gPySetUseEpa,
- METH_VARARGS, (const char *)gPySetUseEpa__doc__},
+ {"setGravity",(PyCFunction) gPySetGravity,
+ METH_VARARGS, (const char*)gPySetGravity__doc__},
+ {"setDebugMode",(PyCFunction) gPySetDebugMode,
+ METH_VARARGS, (const char *)gPySetDebugMode__doc__},
+
+ /// settings that influence quality of the rigidbody dynamics
+ {"setNumIterations",(PyCFunction) gPySetNumIterations,
+ METH_VARARGS, (const char *)gPySetNumIterations__doc__},
+
+ {"setNumTimeSubSteps",(PyCFunction) gPySetNumTimeSubSteps,
+ METH_VARARGS, (const char *)gPySetNumTimeSubSteps__doc__},
+
+ {"setDeactivationTime",(PyCFunction) gPySetDeactivationTime,
+ METH_VARARGS, (const char *)gPySetDeactivationTime__doc__},
+
+ {"setDeactivationLinearTreshold",(PyCFunction) gPySetDeactivationLinearTreshold,
+ METH_VARARGS, (const char *)gPySetDeactivationLinearTreshold__doc__},
+ {"setDeactivationAngularTreshold",(PyCFunction) gPySetDeactivationAngularTreshold,
+ METH_VARARGS, (const char *)gPySetDeactivationAngularTreshold__doc__},
+
+ {"setContactBreakingTreshold",(PyCFunction) gPySetContactBreakingTreshold,
+ METH_VARARGS, (const char *)gPySetContactBreakingTreshold__doc__},
+ {"setCcdMode",(PyCFunction) gPySetCcdMode,
+ METH_VARARGS, (const char *)gPySetCcdMode__doc__},
+ {"setSorConstant",(PyCFunction) gPySetSorConstant,
+ METH_VARARGS, (const char *)gPySetSorConstant__doc__},
+ {"setSolverTau",(PyCFunction) gPySetSolverTau,
+ METH_VARARGS, (const char *)gPySetSolverTau__doc__},
+ {"setSolverDamping",(PyCFunction) gPySetSolverDamping,
+ METH_VARARGS, (const char *)gPySetSolverDamping__doc__},
+
+ {"setLinearAirDamping",(PyCFunction) gPySetLinearAirDamping,
+ METH_VARARGS, (const char *)gPySetLinearAirDamping__doc__},
+
+ {"setUseEpa",(PyCFunction) gPySetUseEpa,
+ METH_VARARGS, (const char *)gPySetUseEpa__doc__},
{"setSolverType",(PyCFunction) gPySetSolverType,
- METH_VARARGS, (const char *)gPySetSolverType__doc__},
+ METH_VARARGS, (const char *)gPySetSolverType__doc__},
- {"createConstraint",(PyCFunction) gPyCreateConstraint,
- METH_VARARGS, (const char *)gPyCreateConstraint__doc__},
- {"getVehicleConstraint",(PyCFunction) gPyGetVehicleConstraint,
- METH_VARARGS, (const char *)gPyGetVehicleConstraint__doc__},
+ {"createConstraint",(PyCFunction) gPyCreateConstraint,
+ METH_VARARGS, (const char *)gPyCreateConstraint__doc__},
+ {"getVehicleConstraint",(PyCFunction) gPyGetVehicleConstraint,
+ METH_VARARGS, (const char *)gPyGetVehicleConstraint__doc__},
- {"removeConstraint",(PyCFunction) gPyRemoveConstraint,
- METH_VARARGS, (const char *)gPyRemoveConstraint__doc__},
+ {"removeConstraint",(PyCFunction) gPyRemoveConstraint,
+ METH_VARARGS, (const char *)gPyRemoveConstraint__doc__},
{"getAppliedImpulse",(PyCFunction) gPyGetAppliedImpulse,
- METH_VARARGS, (const char *)gPyGetAppliedImpulse__doc__},
+ METH_VARARGS, (const char *)gPyGetAppliedImpulse__doc__},
- {"exportBulletFile",(PyCFunction)gPyExportBulletFile,
- METH_VARARGS, "export a .bullet file"},
+ {"exportBulletFile",(PyCFunction)gPyExportBulletFile,
+ METH_VARARGS, "export a .bullet file"},
-
- //sentinel
- { NULL, (PyCFunction) NULL, 0, NULL }
+ //sentinel
+ { NULL, (PyCFunction) NULL, 0, NULL }
};
static struct PyModuleDef PhysicsConstraints_module_def = {
@@ -656,12 +657,13 @@ static struct PyModuleDef PhysicsConstraints_module_def = {
0, /* m_free */
};
-PyObject* initPythonConstraintBinding()
+PyObject* initPythonConstraintBinding()
{
- PyObject* ErrorObject;
- PyObject* m;
- PyObject* d;
+ PyObject* ErrorObject;
+ PyObject* m;
+ PyObject* d;
+ PyObject* item;
/* Use existing module where possible
* be careful not to init any runtime vars after this */
@@ -677,21 +679,43 @@ PyObject* initPythonConstraintBinding()
PyDict_SetItemString(PySys_GetObject("modules"), PhysicsConstraints_module_def.m_name, m);
}
- // Add some symbolic constants to the module
- d = PyModule_GetDict(m);
- ErrorObject = PyUnicode_FromString("PhysicsConstraints.error");
- PyDict_SetItemString(d, "error", ErrorObject);
- Py_DECREF(ErrorObject);
-
- // XXXX Add constants here
-
- // Check for errors
- if (PyErr_Occurred())
- {
- Py_FatalError("can't initialize module PhysicsConstraints");
- }
-
- return d;
+ // Add some symbolic constants to the module
+ d = PyModule_GetDict(m);
+ ErrorObject = PyUnicode_FromString("PhysicsConstraints.error");
+ PyDict_SetItemString(d, "error", ErrorObject);
+ Py_DECREF(ErrorObject);
+
+#ifdef USE_BULLET
+ //Debug Modes constants to be used with setDebugMode() python function
+ KX_MACRO_addTypesToDict(d, DBG_NODEBUG, btIDebugDraw::DBG_NoDebug);
+ KX_MACRO_addTypesToDict(d, DBG_DRAWWIREFRAME, btIDebugDraw::DBG_DrawWireframe);
+ KX_MACRO_addTypesToDict(d, DBG_DRAWAABB, btIDebugDraw::DBG_DrawAabb);
+ KX_MACRO_addTypesToDict(d, DBG_DRAWFREATURESTEXT, btIDebugDraw::DBG_DrawFeaturesText);
+ KX_MACRO_addTypesToDict(d, DBG_DRAWCONTACTPOINTS, btIDebugDraw::DBG_DrawContactPoints);
+ KX_MACRO_addTypesToDict(d, DBG_NOHELPTEXT, btIDebugDraw::DBG_NoHelpText);
+ KX_MACRO_addTypesToDict(d, DBG_DRAWTEXT, btIDebugDraw::DBG_DrawText);
+ KX_MACRO_addTypesToDict(d, DBG_PROFILETIMINGS, btIDebugDraw::DBG_ProfileTimings);
+ KX_MACRO_addTypesToDict(d, DBG_ENABLESATCOMPARISION, btIDebugDraw::DBG_EnableSatComparison);
+ KX_MACRO_addTypesToDict(d, DBG_DISABLEBULLETLCP, btIDebugDraw::DBG_DisableBulletLCP);
+ KX_MACRO_addTypesToDict(d, DBG_ENABLECDD, btIDebugDraw::DBG_EnableCCD);
+ KX_MACRO_addTypesToDict(d, DBG_DRAWCONSTRAINTS, btIDebugDraw::DBG_DrawConstraints);
+ KX_MACRO_addTypesToDict(d, DBG_DRAWCONSTRAINTLIMITS, btIDebugDraw::DBG_DrawConstraintLimits);
+ KX_MACRO_addTypesToDict(d, DBG_FASTWIREFRAME, btIDebugDraw::DBG_FastWireframe);
+#endif // USE_BULLET
+
+ //Constraint types to be used with createConstraint() python function
+ KX_MACRO_addTypesToDict(d, POINTTOPOINT_CONSTRAINT, PHY_POINT2POINT_CONSTRAINT);
+ KX_MACRO_addTypesToDict(d, LINEHINGE_CONSTRAINT, PHY_LINEHINGE_CONSTRAINT);
+ KX_MACRO_addTypesToDict(d, ANGULAR_CONSTRAINT, PHY_ANGULAR_CONSTRAINT);
+ KX_MACRO_addTypesToDict(d, CONETWIST_CONSTRAINT, PHY_CONE_TWIST_CONSTRAINT);
+ KX_MACRO_addTypesToDict(d, VEHICLE_CONSTRAINT, PHY_VEHICLE_CONSTRAINT);
+
+ // Check for errors
+ if (PyErr_Occurred()) {
+ Py_FatalError("can't initialize module PhysicsConstraints");
+ }
+
+ return d;
}
@@ -709,7 +733,4 @@ PHY_IPhysicsEnvironment* PHY_GetActiveEnvironment()
return g_CurrentActivePhysicsEnvironment;
}
-
-
#endif // WITH_PYTHON
-
diff --git a/source/tests/CMakeLists.txt b/source/tests/CMakeLists.txt
index d1696223ec6..8fd0d6e7099 100644
--- a/source/tests/CMakeLists.txt
+++ b/source/tests/CMakeLists.txt
@@ -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=6ae36be272d6f84c697e84a8b6463273 --md5_method=FILE
+ --md5=5e804c689896116331fa190a9fabbad4 --md5_method=FILE
)
add_test(export_x3d_nurbs ${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=bba48ca191e8891adb27c59ed4ce4735 --md5_method=FILE
+ --md5=2809ec13a4cab55d265ce7525c5db1b7 --md5_method=FILE
)
@@ -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=cdf8fa8475fda0b9ef565ac09339254b --md5_method=FILE
+ --md5=0940ea889498cd437d503670738639ae --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=642a5a1fa199d5b9bbf1643519ae974d --md5_method=FILE
+ --md5=83dca99a0cb338852b8c85951a44c68a --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=ec1e8965bdbc3bf70707d77f82c2cb9c --md5_method=FILE
+ --md5=c7d9491ffa6264e820ed1e12df63f871 --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=af3b65665687ac92e4aba07b017d87fe --md5_method=FILE
+ --md5=22867f82e1615fd1eae18cfaac8ba035 --md5_method=FILE
)
diff --git a/source/tests/check_deprecated.py b/source/tests/check_deprecated.py
index 11c7ce646b9..856e1f6d272 100644
--- a/source/tests/check_deprecated.py
+++ b/source/tests/check_deprecated.py
@@ -28,6 +28,7 @@ SKIP_DIRS = ("extern",
os.path.join("source", "tests"), # not this dir
)
+
def is_c_header(filename):
ext = splitext(filename)[1]
return (ext in (".h", ".hpp", ".hxx"))
@@ -41,13 +42,16 @@ def is_c(filename):
def is_c_any(filename):
return is_c(filename) or is_c_header(filename)
+
def is_py(filename):
ext = splitext(filename)[1]
return (ext == ".py")
+
def is_source_any(filename):
return is_c_any(filename) or is_py(filename)
+
def source_list(path, filename_check=None):
for dirpath, dirnames, filenames in os.walk(path):
@@ -67,7 +71,7 @@ def deprecations():
/* *DEPRECATED* 2011/7/17 bgl.Buffer.list info text */
Or...
-
+
# *DEPRECATED* 2010/12/22 some.py.func more info */
"""
@@ -105,12 +109,12 @@ def deprecations():
if len(data) != 3:
print(" poorly formatting line:\n"
" %r:%d\n"
- " %s"%
+ " %s" %
(fn, i + 1, l)
)
else:
data = datetime.datetime(*tuple([int(w) for w in data]))
-
+
deprecations_ls.append((data, (fn, i + 1), info))
except:
print("Error file - %r:%d" % (fn, i + 1))
@@ -123,10 +127,11 @@ def deprecations():
return deprecations_ls
+
def main():
import datetime
now = datetime.datetime.now()\
-
+
deps = deprecations()
print("\nAll deprecations...")