Merged 38822-39182
authorJason Hays <jason_hays22@mymail.eku.edu>
Mon, 8 Aug 2011 14:01:21 +0000 (14:01 +0000)
committerJason Hays <jason_hays22@mymail.eku.edu>
Mon, 8 Aug 2011 14:01:21 +0000 (14:01 +0000)
189 files changed:
CMakeLists.txt
SConstruct
build_files/buildbot/config/user-config-i686.py
build_files/buildbot/config/user-config-player-i686.py
build_files/buildbot/config/user-config-player-x86_64.py
build_files/buildbot/config/user-config-x86_64.py
build_files/buildbot/master.cfg
build_files/buildbot/slave_compile.py
build_files/buildbot/slave_pack.py
build_files/cmake/Modules/FindSpacenav.cmake [new file with mode: 0644]
build_files/cmake/cmake_consistency_check.py
build_files/cmake/cmake_netbeans_project.py
build_files/cmake/cmake_qtcreator_project.py
build_files/cmake/macros.cmake
build_files/scons/config/darwin-config.py
build_files/scons/config/linux2-config.py
build_files/scons/config/win32-vc-config.py
build_files/scons/config/win64-vc-config.py
build_files/scons/tools/Blender.py
build_files/scons/tools/btools.py
doc/python_api/blender-org/static/default.css_t
doc/python_api/rst/bge.constraints.rst
doc/python_api/rst/bge.events.rst
doc/python_api/rst/bge.logic.rst
doc/python_api/rst/bge.render.rst
doc/python_api/rst/bge.texture.rst
doc/python_api/rst/bge.types.rst
doc/python_api/rst/bgl.rst
doc/python_api/sphinx_doc_gen.py
intern/ghost/CMakeLists.txt
intern/ghost/GHOST_C-api.h
intern/ghost/GHOST_ISystem.h
intern/ghost/GHOST_Types.h
intern/ghost/SConscript
intern/ghost/intern/GHOST_C-api.cpp
intern/ghost/intern/GHOST_DisplayManagerWin32.cpp
intern/ghost/intern/GHOST_DropTargetWin32.cpp
intern/ghost/intern/GHOST_DropTargetWin32.h
intern/ghost/intern/GHOST_EventManager.cpp
intern/ghost/intern/GHOST_EventNDOF.h
intern/ghost/intern/GHOST_NDOFManager.cpp
intern/ghost/intern/GHOST_NDOFManager.h
intern/ghost/intern/GHOST_NDOFManagerCocoa.h [new file with mode: 0644]
intern/ghost/intern/GHOST_NDOFManagerCocoa.mm [new file with mode: 0644]
intern/ghost/intern/GHOST_NDOFManagerWin32.cpp [new file with mode: 0644]
intern/ghost/intern/GHOST_NDOFManagerWin32.h [new file with mode: 0644]
intern/ghost/intern/GHOST_NDOFManagerX11.cpp [new file with mode: 0644]
intern/ghost/intern/GHOST_NDOFManagerX11.h [new file with mode: 0644]
intern/ghost/intern/GHOST_System.cpp
intern/ghost/intern/GHOST_System.h
intern/ghost/intern/GHOST_SystemCocoa.h
intern/ghost/intern/GHOST_SystemCocoa.mm
intern/ghost/intern/GHOST_SystemPathsWin32.cpp
intern/ghost/intern/GHOST_SystemPathsWin32.h
intern/ghost/intern/GHOST_SystemPathsX11.cpp
intern/ghost/intern/GHOST_SystemSDL.cpp
intern/ghost/intern/GHOST_SystemWin32.cpp
intern/ghost/intern/GHOST_SystemWin32.h
intern/ghost/intern/GHOST_SystemX11.cpp
intern/ghost/intern/GHOST_SystemX11.h
intern/ghost/intern/GHOST_TaskbarWin32.h
intern/ghost/intern/GHOST_WindowWin32.h
release/scripts/modules/addon_utils.py
release/scripts/modules/bpy/__init__.py
release/scripts/modules/bpy/path.py
release/scripts/modules/bpy/utils.py
release/scripts/modules/bpy_extras/__init__.py
release/scripts/modules/bpy_extras/image_utils.py
release/scripts/modules/bpy_extras/io_utils.py
release/scripts/modules/bpy_extras/mesh_utils.py
release/scripts/modules/bpy_extras/object_utils.py
release/scripts/modules/bpy_extras/view3d_utils.py
release/scripts/modules/bpyml.py
release/scripts/modules/bpyml_ui.py
release/scripts/modules/keyingsets_utils.py
release/scripts/modules/rna_info.py
release/scripts/presets/ffmpeg/xvid.py
release/scripts/startup/bl_operators/image.py
release/scripts/startup/bl_operators/uvcalc_lightmap.py
release/scripts/startup/bl_operators/wm.py
release/scripts/startup/bl_ui/properties_material.py
release/scripts/startup/bl_ui/properties_particle.py
release/scripts/startup/bl_ui/space_userpref.py
release/scripts/startup/bl_ui/space_userpref_keymap.py
release/scripts/startup/bl_ui/space_view3d_toolbar.py
release/scripts/templates/addon_add_object.py
release/scripts/templates/operator_modal.py
release/scripts/templates/operator_modal_draw.py
release/scripts/templates/operator_modal_view3d.py
source/blender/blenkernel/BKE_curve.h
source/blender/blenkernel/BKE_global.h
source/blender/blenkernel/BKE_material.h
source/blender/blenkernel/intern/DerivedMesh.c
source/blender/blenkernel/intern/blender.c
source/blender/blenkernel/intern/curve.c
source/blender/blenkernel/intern/ipo.c
source/blender/blenkernel/intern/key.c
source/blender/blenkernel/intern/material.c
source/blender/blenkernel/intern/mesh.c
source/blender/blenlib/intern/BLI_args.c
source/blender/blenlib/intern/pbvh.c
source/blender/blenloader/BLO_readfile.h
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/writefile.c
source/blender/editors/curve/editcurve.c
source/blender/editors/curve/editfont.c
source/blender/editors/gpencil/gpencil_paint.c
source/blender/editors/include/BIF_glutil.h
source/blender/editors/include/ED_object.h
source/blender/editors/include/ED_transform.h
source/blender/editors/include/UI_interface.h
source/blender/editors/include/UI_resources.h
source/blender/editors/interface/interface.c
source/blender/editors/interface/interface_anim.c
source/blender/editors/interface/interface_handlers.c
source/blender/editors/interface/interface_icons.c
source/blender/editors/interface/interface_layout.c
source/blender/editors/interface/interface_regions.c
source/blender/editors/interface/interface_style.c
source/blender/editors/interface/interface_templates.c
source/blender/editors/interface/interface_utils.c
source/blender/editors/interface/interface_widgets.c
source/blender/editors/interface/resources.c
source/blender/editors/object/object_edit.c
source/blender/editors/object/object_relations.c
source/blender/editors/screen/glutil.c
source/blender/editors/screen/screen_ops.c
source/blender/editors/sculpt_paint/paint_image.c
source/blender/editors/sculpt_paint/paint_stroke.c
source/blender/editors/space_file/file_ops.c
source/blender/editors/space_image/image_intern.h
source/blender/editors/space_image/image_ops.c
source/blender/editors/space_image/space_image.c
source/blender/editors/space_node/drawnode.c
source/blender/editors/space_sequencer/sequencer_draw.c
source/blender/editors/space_sequencer/sequencer_edit.c
source/blender/editors/space_view3d/view3d_draw.c
source/blender/editors/space_view3d/view3d_edit.c
source/blender/editors/space_view3d/view3d_fly.c
source/blender/editors/space_view3d/view3d_header.c
source/blender/editors/space_view3d/view3d_intern.h
source/blender/editors/space_view3d/view3d_ops.c
source/blender/editors/space_view3d/view3d_select.c
source/blender/editors/space_view3d/view3d_view.c
source/blender/editors/transform/CMakeLists.txt
source/blender/editors/transform/transform.c
source/blender/editors/transform/transform.h
source/blender/editors/transform/transform_generics.c
source/blender/editors/transform/transform_ndofinput.c [deleted file]
source/blender/editors/transform/transform_ops.c
source/blender/makesdna/DNA_space_types.h
source/blender/makesdna/DNA_userdef_types.h
source/blender/makesdna/DNA_view3d_types.h
source/blender/makesdna/DNA_windowmanager_types.h
source/blender/makesrna/RNA_access.h
source/blender/makesrna/intern/rna_ID.c
source/blender/makesrna/intern/rna_access.c
source/blender/makesrna/intern/rna_action.c
source/blender/makesrna/intern/rna_internal.h
source/blender/makesrna/intern/rna_object_api.c
source/blender/makesrna/intern/rna_scene.c
source/blender/makesrna/intern/rna_userdef.c
source/blender/makesrna/intern/rna_wm.c
source/blender/makesrna/intern/rna_wm_api.c
source/blender/modifiers/intern/MOD_uvproject.c
source/blender/python/intern/bpy_driver.c
source/blender/python/intern/bpy_library.c
source/blender/python/intern/bpy_operator.c
source/blender/python/intern/bpy_props.c
source/blender/python/intern/bpy_rna.c
source/blender/python/intern/bpy_rna.h
source/blender/render/intern/source/rendercore.c
source/blender/windowmanager/CMakeLists.txt
source/blender/windowmanager/WM_api.h
source/blender/windowmanager/WM_keymap.h [new file with mode: 0644]
source/blender/windowmanager/WM_types.h
source/blender/windowmanager/intern/wm.c
source/blender/windowmanager/intern/wm_event_system.c
source/blender/windowmanager/intern/wm_files.c
source/blender/windowmanager/intern/wm_init_exit.c
source/blender/windowmanager/intern/wm_keymap.c
source/blender/windowmanager/intern/wm_operators.c
source/blender/windowmanager/intern/wm_window.c
source/blender/windowmanager/wm_event_types.h
source/blenderplayer/bad_level_call_stubs/stubs.c
source/gameengine/Converter/KX_BlenderSceneConverter.cpp
source/gameengine/Ketsji/KX_PyConstraintBinding.cpp
source/tests/CMakeLists.txt
source/tests/bl_run_operators.py

index d4489a8..cf083b8 100644 (file)
@@ -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,28 @@ 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()
+
+                       if(WITH_INPUT_NDOF)
+                               set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -weak_framework 3DconnexionClient")
+                       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 +1059,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 +1088,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 +1354,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)
index 053f414..7b25f74 100644 (file)
@@ -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,12 +246,30 @@ 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():
         if k not in B.arguments:
             env[k] = v
 
+# Extended OSX_SDK and 3D_CONNEXION_CLIENT_LIBRARY detection for OSX
+if env['OURPLATFORM']=='darwin':
+    print B.bc.OKGREEN + "Detected Xcode version: -- " + B.bc.ENDC + env['XCODE_CUR_VER'][:9] + " --"
+    print "Available " + env['MACOSX_SDK_CHECK']
+    if not 'Mac OS X 10.5' in env['MACOSX_SDK_CHECK']:
+        print  B.bc.OKGREEN + "MacOSX10.5.sdk not available:" + B.bc.ENDC + " using MacOSX10.6.sdk"
+    else:
+        print B.bc.OKGREEN + "Found recommended sdk :" + B.bc.ENDC + " using MacOSX10.5.sdk"
+
+    # for now, Mac builders must download and install the driver framework from 3Dconnexion
+    # necessary header file lives here when installed:
+    # /Library/Frameworks/3DconnexionClient.framework/Versions/Current/Headers/ConnexionClientAPI.h
+    if env['WITH_BF_3DMOUSE'] == 1 and not os.path.exists('/Library/Frameworks/3DconnexionClient.framework'):
+        print "3D_CONNEXION_CLIENT_LIBRARY not found, disabling WITH_BF_3DMOUSE" # avoid build errors !
+        env['WITH_BF_3DMOUSE'] = 0
+        env['FOUND_NDOF_DRIVERS'] = 0
+
 
 if env['WITH_BF_OPENMP'] == 1:
         if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
@@ -658,11 +681,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
index 1ad6c5d..e09fece 100644 (file)
@@ -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']
index 241f5a7..279f2d6 100644 (file)
@@ -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']
index d51894b..d191433 100644 (file)
@@ -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']
index 3eaadd9..bdba889 100644 (file)
@@ -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']
index fd712f1..1e70ec5 100644 (file)
@@ -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)
 
index e74d889..b83a65f 100644 (file)
@@ -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)
index 4c19b72..5fdeb4a 100644 (file)
@@ -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 (file)
index 0000000..206f361
--- /dev/null
@@ -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
+)
index ba71603..880cb58 100755 (executable)
@@ -39,7 +39,7 @@ 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())]
 
index 8060574..02dfec0 100755 (executable)
@@ -37,7 +37,7 @@ from project_info import (SIMPLE_PROJECTFILE,
                           source_list,
                           is_project_file,
                           is_c_header,
-                          is_py,
+                          is_py,
                           cmake_advanced_info,
                           cmake_compiler_defines,
                           )
index d8993c3..2a2774c 100755 (executable)
@@ -33,7 +33,7 @@ example linux usage
 
 from project_info import (SIMPLE_PROJECTFILE,
                           SOURCE_DIR,
-                          CMAKE_DIR,
+                          CMAKE_DIR,
                           PROJECT_DIR,
                           source_list,
                           is_project_file,
index 3430145..27694bc 100644 (file)
@@ -62,6 +62,10 @@ macro(blender_include_dirs
        foreach(_INC ${ARGV})
                get_filename_component(_ABS_INC ${_INC} ABSOLUTE)
                list(APPEND _ALL_INCS ${_ABS_INC})
+               # for checking for invalid includes, disable for regular use
+               ##if(NOT EXISTS "${_ABS_INC}/")
+               ##      message(FATAL_ERROR "Include not found: ${_ABS_INC}/")
+               ##endif()
        endforeach()
        include_directories(${_ALL_INCS})
        unset(_INC)
@@ -75,6 +79,9 @@ macro(blender_include_dirs_sys
        foreach(_INC ${ARGV})
                get_filename_component(_ABS_INC ${_INC} ABSOLUTE)
                list(APPEND _ALL_INCS ${_ABS_INC})
+               ##if(NOT EXISTS "${_ABS_INC}/")
+               ##      message(FATAL_ERROR "Include not found: ${_ABS_INC}/")
+               ##endif()
        endforeach()
        include_directories(SYSTEM ${_ALL_INCS})
        unset(_INC)
@@ -314,6 +321,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()
index 0c51476..2969589 100644 (file)
@@ -21,14 +21,23 @@ cmd = 'uname -p'
 MAC_PROC=commands.getoutput(cmd) 
 cmd = 'uname -r'
 cmd_res=commands.getoutput(cmd) 
-if cmd_res[0]=='7':
+
+if cmd_res[:1]=='7':
        MAC_CUR_VER='10.3'
-elif cmd_res[0]=='8':
+elif cmd_res[:1]=='8':
        MAC_CUR_VER='10.4'
-elif cmd_res[0]=='9':
+elif cmd_res[:1]=='9':
        MAC_CUR_VER='10.5'
-elif cmd_res[0]=='10':
+elif cmd_res[:2]=='10':
        MAC_CUR_VER='10.6'
+elif cmd_res[:2]=='11':
+       MAC_CUR_VER='10.7'
+cmd = 'xcodebuild -version'
+cmd_xcode=commands.getoutput(cmd)
+XCODE_CUR_VER=cmd_xcode
+cmd = 'xcodebuild -showsdks'
+cmd_sdk=commands.getoutput(cmd)
+MACOSX_SDK_CHECK=cmd_sdk
 
 if MACOSX_ARCHITECTURE == 'x86_64' or MACOSX_ARCHITECTURE == 'ppc64':
        USE_QTKIT=True # Carbon quicktime is not available for 64bit
@@ -37,8 +46,8 @@ if MACOSX_ARCHITECTURE == 'x86_64' or MACOSX_ARCHITECTURE == 'ppc64':
 # Default target OSX settings per architecture
 # Can be customized
 
-if MACOSX_ARCHITECTURE == 'ppc':
-# ppc release are now made for 10.4
+if MACOSX_ARCHITECTURE == 'ppc' and MAC_CUR_VER == '10.4':
+# all releases are now made for 10.5 !
 #      MAC_MIN_VERS = '10.3'
 #      MACOSX_SDK='/Developer/SDKs/MacOSX10.3.9.sdk'
 #      LCGDIR = '#../lib/darwin-6.1-powerpc'
@@ -50,7 +59,7 @@ if MACOSX_ARCHITECTURE == 'ppc':
        LCGDIR = '#../lib/darwin-8.0.0-powerpc'
        CC = 'gcc-4.0'
        CXX = 'g++-4.0'
-elif MACOSX_ARCHITECTURE == 'i386':
+elif MACOSX_ARCHITECTURE == 'i386' and MAC_CUR_VER == '10.4':
        MAC_MIN_VERS = '10.4'
        MACOSX_DEPLOYMENT_TARGET = '10.4'
        MACOSX_SDK='/Developer/SDKs/MacOSX10.4u.sdk'
@@ -58,12 +67,22 @@ elif MACOSX_ARCHITECTURE == 'i386':
        CC = 'gcc-4.0'
        CXX = 'g++-4.0'
 else :
-       MAC_MIN_VERS = '10.5'
-       MACOSX_DEPLOYMENT_TARGET = '10.5'
-       MACOSX_SDK='/Developer/SDKs/MacOSX10.5.sdk'
-       LCGDIR = '#../lib/darwin-9.x.universal'
-       CC = 'gcc-4.2'
-       CXX = 'g++-4.2'
+       if 'Mac OS X 10.5' in MACOSX_SDK_CHECK:
+               # OSX 10.5/6 with Xcode 3.x
+               MAC_MIN_VERS = '10.5'
+               MACOSX_DEPLOYMENT_TARGET = '10.5'
+               MACOSX_SDK='/Developer/SDKs/MacOSX10.5.sdk'
+               LCGDIR = '#../lib/darwin-9.x.universal'
+               CC = 'gcc-4.2'
+               CXX = 'g++-4.2'
+       else:
+               # OSX 10.6/7 with Xcode 4.x
+               MAC_MIN_VERS = '10.6'
+               MACOSX_DEPLOYMENT_TARGET = '10.6'
+               MACOSX_SDK='/Developer/SDKs/MacOSX10.6.sdk'
+               LCGDIR = '#../lib/darwin-9.x.universal'
+               CC = 'gcc-4.2'
+               CXX = 'g++-4.2'
 
 LIBDIR = '${LCGDIR}'
 
@@ -71,8 +90,8 @@ LIBDIR = '${LCGDIR}'
 ###################          Dependency settings           ##################
 #############################################################################
 
-#Defaults openMP to true if compiler (currently only gcc 4.2) handles it
-if CC == 'gcc-4.2':
+#Defaults openMP to true if compiler handles it
+if CC == 'gcc-4.2' or CC == 'llvm-gcc-4.2':
     WITH_BF_OPENMP = True  # multithreading for fluids, cloth and smoke
 else:
     WITH_BF_OPENMP = False
@@ -188,8 +207,8 @@ BF_GETTEXT_INC = '${BF_GETTEXT}/include'
 BF_GETTEXT_LIB = 'intl'
 BF_GETTEXT_LIBPATH = '${BF_GETTEXT}/lib'
 
-WITH_BF_GAMEENGINE=True
-WITH_BF_PLAYER = False
+WITH_BF_GAMEENGINE = True
+WITH_BF_PLAYER = True
 
 WITH_BF_BULLET = True
 BF_BULLET = '#extern/bullet2/src'
@@ -240,7 +259,7 @@ BF_OPENGL_LIBPATH = '/System/Library/Frameworks/OpenGL.framework/Libraries'
 BF_OPENGL_LINKFLAGS = ['-framework', 'OpenGL']
 
 #OpenCollada flags
-WITH_BF_COLLADA = False
+WITH_BF_COLLADA = True
 BF_COLLADA = '#source/blender/collada'
 BF_COLLADA_INC = '${BF_COLLADA}'
 BF_COLLADA_LIB = 'bf_collada'
@@ -264,7 +283,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 = True
 
 #############################################################################
 ###################  various compile settings and flags    ##################
@@ -283,28 +304,31 @@ CPPFLAGS = []+ARCH_FLAGS
 CCFLAGS = ['-pipe','-funsigned-char']+ARCH_FLAGS
 CXXFLAGS = ['-pipe','-funsigned-char']+ARCH_FLAGS
 
-if WITH_GHOST_COCOA==True:
+if WITH_GHOST_COCOA:
        PLATFORM_LINKFLAGS = ['-fexceptions','-framework','CoreServices','-framework','Foundation','-framework','IOKit','-framework','AppKit','-framework','Cocoa','-framework','Carbon','-framework','AudioUnit','-framework','AudioToolbox','-framework','CoreAudio','-framework','OpenAL']+ARCH_FLAGS
 else:
        PLATFORM_LINKFLAGS = ['-fexceptions','-framework','CoreServices','-framework','Foundation','-framework','IOKit','-framework','AppKit','-framework','Carbon','-framework','AGL','-framework','AudioUnit','-framework','AudioToolbox','-framework','CoreAudio','-framework','OpenAL']+ARCH_FLAGS
 
-if WITH_BF_QUICKTIME == True:
-       if USE_QTKIT == True:
+if WITH_BF_QUICKTIME:
+       if USE_QTKIT:
                PLATFORM_LINKFLAGS = PLATFORM_LINKFLAGS+['-framework','QTKit']
        else:
                PLATFORM_LINKFLAGS = PLATFORM_LINKFLAGS+['-framework','QuickTime']
 
+if FOUND_NDOF_DRIVERS:
+       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']
 
-# some flags shuffling for different Os versions
+# some flags shuffling for different OS versions
 if MAC_MIN_VERS == '10.3':
        CFLAGS = ['-fuse-cxa-atexit']+CFLAGS
        CXXFLAGS = ['-fuse-cxa-atexit']+CXXFLAGS
        PLATFORM_LINKFLAGS = ['-fuse-cxa-atexit']+PLATFORM_LINKFLAGS
        LLIBS.append('crt3.o')
        
-if USE_SDK==True:
+if USE_SDK:
        SDK_FLAGS=['-isysroot', MACOSX_SDK,'-mmacosx-version-min='+MAC_MIN_VERS,'-arch',MACOSX_ARCHITECTURE]    
        PLATFORM_LINKFLAGS = ['-mmacosx-version-min='+MAC_MIN_VERS,'-Wl','-isysroot',MACOSX_SDK,'-arch',MACOSX_ARCHITECTURE]+PLATFORM_LINKFLAGS
        CCFLAGS=SDK_FLAGS+CCFLAGS
index 328cd4c..d8e227c 100644 (file)
@@ -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++'
index 89b246c..4baada7 100644 (file)
@@ -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']
index 67db1c4..db7c8d0 100644 (file)
@@ -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']
index 75af7e4..6fae278 100644 (file)
@@ -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
index 677ddab..aac1655 100644 (file)
@@ -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', 'FOUND_NDOF_DRIVERS', '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
@@ -149,7 +149,7 @@ def validate_arguments(args, bc):
             'BF_PROFILE_CFLAGS', 'BF_PROFILE_CCFLAGS', 'BF_PROFILE_CXXFLAGS', 'BF_PROFILE_LINKFLAGS',
             'BF_DEBUG_CFLAGS', 'BF_DEBUG_CCFLAGS', 'BF_DEBUG_CXXFLAGS',
             'C_WARN', 'CC_WARN', 'CXX_WARN',
-            'LLIBS', 'PLATFORM_LINKFLAGS','MACOSX_ARCHITECTURE',
+            'LLIBS', 'PLATFORM_LINKFLAGS','MACOSX_ARCHITECTURE', 'MACOSX_SDK_CHECK', 'XCODE_CUR_VER',
     ]
     
     
@@ -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,15 @@ 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('FOUND_NDOF_DRIVERS', 'We detected NDOF libs or framework', 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', []),
@@ -453,6 +463,8 @@ def read_opts(env, cfg, args):
         ('LLIBS', 'Platform libs', []),
         ('PLATFORM_LINKFLAGS', 'Platform linkflags', []),
         ('MACOSX_ARCHITECTURE', 'python_arch.zip select', ''),
+        ('MACOSX_SDK_CHECK', 'detect available OSX sdk`s', ''),
+        ('XCODE_CUR_VER', 'detect XCode version', ''),
 
         (BoolVariable('BF_PROFILE', 'Add profiling information if true', False)),
         ('BF_PROFILE_CFLAGS', 'C only profiling flags', []),
index 6f3f25d..e6fe922 100644 (file)
@@ -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 {
index 882bbc3..da0a358 100644 (file)
@@ -1,28 +1,51 @@
 
-Game Engine bge.constraints Module
-==================================
+Physics Constraints (bge.constraints)
+=====================================
 
-.. note::
-   This documentation is still very weak, and needs some help!
+.. module:: bge.constraints
 
-.. function:: createConstraint([obj1, [obj2, [restLength, [restitution, [damping]]]]])
+.. literalinclude:: ../examples/bge.constraints.py
+
+.. 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 +72,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 +83,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 +96,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 +127,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 +160,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 +181,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 +194,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 +214,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 +222,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
index cc76ecd..074e928 100644 (file)
@@ -1,6 +1,6 @@
 
-Game Engine bge.events Module
-=============================
+Game Keys (bge.events)
+======================
 
 *****
 Intro
index f7163ea..128f87f 100644 (file)
@@ -1,6 +1,7 @@
 
-Game Engine bge.logic Module
-============================
+Game Logic (bge.logic)
+======================
+
 *****
 Intro
 *****
index 9f17455..1051404 100644 (file)
@@ -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
index 996f79a..0b32c7a 100644 (file)
@@ -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
@@ -40,6 +36,10 @@ When the texture object is deleted, the new texture is deleted and the old textu
 
 .. module:: bge.texture
 
+.. literalinclude:: ../examples/bge.texture.py
+
+.. literalinclude:: ../examples/bge.texture.1.py
+
 .. class:: VideoFFmpeg(file [, capture=-1, rate=25.0, width=0, height=0])
 
    FFmpeg video source
index e42b362..36ef915 100644 (file)
@@ -1,6 +1,6 @@
 
-Game Engine  bge.types Module
-=============================
+Game Types (bge.types)
+======================
 
 .. module:: bge.types
 
index 76b7442..5f3158b 100644 (file)
@@ -1,6 +1,6 @@
 
-bgl module (OpenGL wrapper)
-===========================
+OpenGL Wrapper (bgl)
+====================
 
 .. module:: bgl
 
@@ -15,7 +15,7 @@ collections of tutorials.
 The "red book": "I{OpenGL Programming Guide: The Official Guide to Learning
 OpenGL}" and the online NeHe tutorials are two of the best resources.
 
-..note::
+.. note::
    You can use the :class:`Image` type to load and set textures.
    See :class:`Image.gl_load` and :class:`Image.gl_load`,
    for example.
@@ -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):
@@ -1386,7 +1386,7 @@ OpenGL}" and the online NeHe tutorials are two of the best resources.
         bgl.glGetFloatv(bgl.GL_MODELVIEW_MATRIX, view_matrix)
         f = 1.0 / view_matrix[0]
 
-               # Instead of the usual glRasterPos2i(xval, yval)
+        # Instead of the usual glRasterPos2i(xval, yval)
         bgl.glRasterPos2f(xval * f, yval * f)
 
 
@@ -1848,10 +1848,13 @@ class Buffer:
    .. code-block:: python
 
       import bgl
+
       myByteBuffer = bgl.Buffer(bgl.GL_BYTE, [32, 32])
       bgl.glGetPolygonStipple(myByteBuffer)
+
       print(myByteBuffer.dimensions)
       print(myByteBuffer.to_list())
+
       sliceBuffer = myByteBuffer[0:16]
       print(sliceBuffer)
 
@@ -1886,4 +1889,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.
-
index 6b514cf..f8561c7 100644 (file)
@@ -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
index ccd763e..bdda0f3 100644 (file)
@@ -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)
@@ -138,6 +149,10 @@ if(WITH_HEADLESS OR WITH_GHOST_SDL)
                        intern/GHOST_SystemPathsX11.cpp
                        intern/GHOST_SystemPathsX11.h
                )
+
+               if(NOT WITH_INSTALL_PORTABLE)
+                       add_definitions(-DPREFIX="${CMAKE_INSTALL_PREFIX}")
+               endif()
        elseif(WIN32)
 
                list(APPEND SRC
@@ -158,12 +173,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
@@ -184,10 +208,6 @@ elseif(APPLE)
 
 elseif(UNIX)
 
-       if(WITH_X11_XINPUT)
-               add_definitions(-DWITH_X11_XINPUT)
-       endif()
-
        list(APPEND INC_SYS
                ${X11_X11_INCLUDE_PATH}
        )
@@ -204,10 +224,6 @@ elseif(UNIX)
                intern/GHOST_WindowX11.h
        )
 
-       if(NOT WITH_INSTALL_PORTABLE)
-               add_definitions(-DPREFIX="${CMAKE_INSTALL_PREFIX}")
-       endif()
-
        if(X11_XF86keysym_INCLUDE_PATH)
                add_definitions(-DWITH_XF86KEYSYM)
                list(APPEND INC_SYS
@@ -215,6 +231,22 @@ elseif(UNIX)
                )
        endif()
 
+       if(WITH_INPUT_NDOF)
+               list(APPEND SRC
+                       intern/GHOST_NDOFManagerX11.cpp
+
+                       intern/GHOST_NDOFManagerX11.h
+               )
+       endif()
+
+       if(NOT WITH_INSTALL_PORTABLE)
+               add_definitions(-DPREFIX="${CMAKE_INSTALL_PREFIX}")
+       endif()
+
+       if(WITH_X11_XINPUT)
+               add_definitions(-DWITH_X11_XINPUT)
+       endif()
+
 elseif(WIN32)
        if(MSVC)
                set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /WX")
@@ -238,6 +270,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}")
index 7583723..a315dfa 100644 (file)
@@ -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
index 69e1007..015ae78 100644 (file)
@@ -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
         ***************************************************************************************/
index 6a4da5c..f24ab00 100644 (file)
@@ -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. */
index c65ec58..234fc0a 100644 (file)
@@ -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
index 7ba8d7d..6332d72 100644 (file)
@@ -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;
index 30d9aa3..47f7489 100644 (file)
 #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>
index 2e77da4..99990a4 100644 (file)
@@ -33,6 +33,7 @@
  
 #include "GHOST_Debug.h"
 #include "GHOST_DropTargetWin32.h"
+#include <ShellApi.h>
 
 #ifdef GHOST_DEBUG
 // utility
index 0a553b6..980e9f9 100644 (file)
@@ -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"
index 1483555..86b8797 100644 (file)
@@ -42,7 +42,7 @@
 #include "GHOST_EventManager.h"
 #include <algorithm>
 #include "GHOST_Debug.h"
-
+#include <stdio.h> // [mce] temp debug
 
 GHOST_EventManager::GHOST_EventManager()
 {
index 70861b0..394aff0 100644 (file)
  *
  * ***** END GPL LICENSE BLOCK *****
  */
-
-/** \file ghost/intern/GHOST_EventNDOF.h
- *  \ingroup GHOST
- */
-
  
 
 #ifndef _GHOST_EVENT_NDOF_H_
 
 #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_
-
index dae6cb5..a24ccc3 100644 (file)
@@ -1,4 +1,6 @@
 /*
+ * $Id$
+ *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
  * This program is free software; you can redistribute it and/or
  * 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.f)
+       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 HOME(foo) (fabsf(ndof->foo) < threshold)
+               return HOME(tx) && HOME(ty) && HOME(tz) && HOME(rx) && HOME(ry) && HOME(rz);
+#undef HOME
+       }
+}
+
+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 weHaveMotion = !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 (weHaveMotion) {
+                               data->progress = GHOST_kStarting;
+                               m_motionState = GHOST_kInProgress;
+                               // prev motion time will be ancient, so just make up a reasonable time delta
+                               data->dt = 0.0125f;
+                       }
+                       else {
+                               // send no event and keep current state
+                               delete event;
+                               return false;
+                       }
+                       break;
+               case GHOST_kInProgress:
+                       if (weHaveMotion) {
+                               data->progress = GHOST_kInProgress;
+                               // remain 'InProgress'
+                       }
+                       else {
+                               data->progress = GHOST_kFinishing;
+                               m_motionState = GHOST_kFinished;
+                       }
+                       break;
+               default:
+                       ; // will always be one of the above
+       }
+
+#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;
 }
index c9e0937..5bdbe7a 100644 (file)
@@ -1,4 +1,6 @@
 /*
+ * $Id$
+ *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
  * This program is free software; you can redistribute it and/or
  * 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 (file)
index 0000000..e9897f3
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * $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_
+
+#ifdef WITH_INPUT_NDOF
+
+#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 // WITH_INPUT_NDOF
+#endif // #include guard
diff --git a/intern/ghost/intern/GHOST_NDOFManagerCocoa.mm b/intern/ghost/intern/GHOST_NDOFManagerCocoa.mm
new file mode 100644 (file)
index 0000000..1d90b6d
--- /dev/null
@@ -0,0 +1,176 @@
+/*
+ * $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 *****
+ */
+
+#ifdef WITH_INPUT_NDOF
+
+#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
+}
+
+#endif // WITH_INPUT_NDOF
diff --git a/intern/ghost/intern/GHOST_NDOFManagerWin32.cpp b/intern/ghost/intern/GHOST_NDOFManagerWin32.cpp
new file mode 100644 (file)
index 0000000..fd62e84
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * $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 *****
+ */
+
+#ifdef WITH_INPUT_NDOF // use contents of this file
+
+#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;
+}
+
+#endif // WITH_INPUT_NDOF
diff --git a/intern/ghost/intern/GHOST_NDOFManagerWin32.h b/intern/ghost/intern/GHOST_NDOFManagerWin32.h
new file mode 100644 (file)
index 0000000..9f3edde
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * $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_
+
+#ifdef WITH_INPUT_NDOF
+
+#include "GHOST_NDOFManager.h"
+
+
+class GHOST_NDOFManagerWin32 : public GHOST_NDOFManager
+{
+public:
+       GHOST_NDOFManagerWin32(GHOST_System&);
+       bool available();
+};
+
+
+#endif // WITH_INPUT_NDOF
+#endif // #include guard
diff --git a/intern/ghost/intern/GHOST_NDOFManagerX11.cpp b/intern/ghost/intern/GHOST_NDOFManagerX11.cpp
new file mode 100644 (file)
index 0000000..4dd5331
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * $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 *****
+ */
+
+#ifdef WITH_INPUT_NDOF
+
+#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 {
+               puts("ndof: spacenavd not found");
+               /* 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::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;
+}
+
+#endif /* WITH_INPUT_NDOF */
diff --git a/intern/ghost/intern/GHOST_NDOFManagerX11.h b/intern/ghost/intern/GHOST_NDOFManagerX11.h
new file mode 100644 (file)
index 0000000..0a54975
--- /dev/null
@@ -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_NDOFMANAGERX11_H_
+#define _GHOST_NDOFMANAGERX11_H_
+
+#ifdef WITH_INPUT_NDOF
+
+#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 m_available;
+};
+
+#endif /* WITH_INPUT_NDOF */
+#endif /* #include guard */
+
index cb3e97f..64c2c21 100644 (file)
 
 
 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;
 }
 
index b5c64bf..c1e7091 100644 (file)
@@ -190,25 +190,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_
 
index ce77735..d20aed6 100644 (file)
@@ -220,6 +220,11 @@ public:
      */
     GHOST_TSuccess handleApplicationBecomeActiveEvent();
 
+       /**
+        * External objects should call this when they send an event outside processEvents.
+        */
+       void notifyExternalEventProcessed();
+
        /**
         * @see GHOST_ISystem
         */
@@ -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 */
index bb3d6e3..303c2b2 100644 (file)
@@ -21,8 +21,8 @@
  *
  * The Original Code is: all of this file.
  *
- * Contributor(s):     Maarten Gribnau 05/2001
- *                                     Damien Plisson 09/2009
+ * Contributors: Maarten Gribnau 05/2001
+ *               Damien Plisson 09/2009
  *
  * ***** END GPL LICENSE BLOCK *****
  */
 #include "GHOST_EventButton.h"
 #include "GHOST_EventCursor.h"
 #include "GHOST_EventWheel.h"
-#include "GHOST_EventNDOF.h"
 #include "GHOST_EventTrackpad.h"
 #include "GHOST_EventDragnDrop.h"
 #include "GHOST_EventString.h"
-
 #include "GHOST_TimerManager.h"
 #include "GHOST_TimerTask.h"
 #include "GHOST_WindowManager.h"
 #include "GHOST_WindowCocoa.h"
-#include "GHOST_NDOFManager.h"
+#ifdef WITH_INPUT_NDOF
+#include "GHOST_NDOFManagerCocoa.h"
+#endif
+
 #include "AssertMacros.h"
 
 #pragma mark KeyMap, mouse converters
@@ -596,6 +597,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 +1013,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 +1571,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;
index becccc2..523d119 100644 (file)
 
 #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__)
index 67cc214..3de7bbf 100644 (file)
@@ -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"
index dd89357..135f5c4 100644 (file)
 #include <stdio.h> // for fprintf only
 #include <cstdlib> // for exit
 
-using namespace std;
+#ifdef PREFIX
+static const char *static_path= PREFIX "/share" ;
+#else
+static const char *static_path= NULL;
+#endif
 
 GHOST_SystemPathsX11::GHOST_SystemPathsX11()
 {
@@ -56,21 +60,12 @@ GHOST_SystemPathsX11::~GHOST_SystemPathsX11()
 const GHOST_TUns8* GHOST_SystemPathsX11::getSystemDir() const
 {
        /* no prefix assumes a portable build which only uses bundled scripts */
-#ifdef PREFIX
-       return (GHOST_TUns8*) PREFIX "/share";
-#else
-       return NULL;
-#endif
+       return (const GHOST_TUns8 *)static_path;
 }
 
 const GHOST_TUns8* GHOST_SystemPathsX11::getUserDir() const
 {
-       const char* env = getenv("HOME");
-       if(env) {
-               return (GHOST_TUns8*) env;
-       } else {
-               return NULL;
-       }
+       return (const GHOST_TUns8 *)getenv("HOME");
 }
 
 const GHOST_TUns8* GHOST_SystemPathsX11::getBinaryDir() const
index 2c61acc..cd7efba 100644 (file)
@@ -167,6 +167,8 @@ convertSDLKey(SDL_Scancode key)
                GXMAP(type,SDL_SCANCODE_APOSTROPHE,     GHOST_kKeyQuote);
                GXMAP(type,SDL_SCANCODE_GRAVE,          GHOST_kKeyAccentGrave);
                GXMAP(type,SDL_SCANCODE_MINUS,          GHOST_kKeyMinus);
+               GXMAP(type,SDL_SCANCODE_EQUALS,         GHOST_kKeyEqual);
+
                GXMAP(type,SDL_SCANCODE_SLASH,          GHOST_kKeySlash);
                GXMAP(type,SDL_SCANCODE_BACKSLASH,      GHOST_kKeyBackslash);
                GXMAP(type,SDL_SCANCODE_KP_EQUALS,      GHOST_kKeyEqual);
@@ -180,6 +182,7 @@ convertSDLKey(SDL_Scancode key)
                GXMAP(type,SDL_SCANCODE_RCTRL,          GHOST_kKeyRightControl);
                GXMAP(type,SDL_SCANCODE_LALT,           GHOST_kKeyLeftAlt);
                GXMAP(type,SDL_SCANCODE_RALT,           GHOST_kKeyRightAlt);
+               GXMAP(type,SDL_SCANCODE_LGUI,           GHOST_kKeyOS);
                GXMAP(type,SDL_SCANCODE_RGUI,           GHOST_kKeyOS);
 
                GXMAP(type,SDL_SCANCODE_INSERT,         GHOST_kKeyInsert);
@@ -197,6 +200,7 @@ convertSDLKey(SDL_Scancode key)
                GXMAP(type,SDL_SCANCODE_CAPSLOCK,       GHOST_kKeyCapsLock);
                GXMAP(type,SDL_SCANCODE_SCROLLLOCK,     GHOST_kKeyScrollLock);
                GXMAP(type,SDL_SCANCODE_NUMLOCKCLEAR,   GHOST_kKeyNumLock);
+               GXMAP(type,SDL_SCANCODE_PRINTSCREEN,    GHOST_kKeyPrintScreen);
 
                /* keypad events */
 
@@ -228,6 +232,7 @@ convertSDLKey(SDL_Scancode key)
         GXMAP(type,SDL_SCANCODE_AUDIONEXT,      GHOST_kKeyMediaLast);
 
                default:
+                       printf("Unknown\n");
                        type= GHOST_kKeyUnknown;
                        break;
                }
@@ -372,6 +377,7 @@ GHOST_SystemSDL::processEvent(SDL_Event *sdl_event)
        case SDL_KEYUP:
                {
                        SDL_KeyboardEvent &sdl_sub_evt= sdl_event->key;
+                       SDL_Keycode sym= sdl_sub_evt.keysym.sym;
                        GHOST_TEventType type= (sdl_sub_evt.state == SDL_PRESSED) ? GHOST_kEventKeyDown : GHOST_kEventKeyUp;
 
                        GHOST_WindowSDL *window= findGhostWindow(SDL_GetWindowFromID(sdl_sub_evt.windowID));
@@ -379,7 +385,45 @@ GHOST_SystemSDL::processEvent(SDL_Event *sdl_event)
 
                        GHOST_TKey gkey= convertSDLKey(sdl_sub_evt.keysym.scancode);
                        /* note, the sdl_sub_evt.keysym.sym is truncated, for unicode support ghost has to be modified */
-                       g_event= new GHOST_EventKey(getMilliSeconds(), type, window, gkey, sdl_sub_evt.keysym.sym);
+                       if(sym > 127) {
+                               sym= 0;
+                       }
+                       else {
+                               if(sdl_sub_evt.keysym.mod & (KMOD_LSHIFT|KMOD_RSHIFT)) {
+                                       /* lame US keyboard assumptions */
+                                       if(sym >= 'a' && sym <= ('a' + 32)) {
+                                               sym -= 32;
+                                       }
+                                       else {
+                                               switch(sym) {
+                                                       case '`': sym= '~'; break;
+                                                       case '1': sym= '!'; break;
+                                                       case '2': sym= '@'; break;
+                                                       case '3': sym= '#'; break;
+                                                       case '4': sym= '$'; break;
+                                                       case '5': sym= '%'; break;
+                                                       case '6': sym= '^'; break;
+                                                       case '7': sym= '&'; break;
+                                                       case '8': sym= '*'; break;
+                                                       case '9': sym= '('; break;
+                                                       case '0': sym= ')'; break;
+                                                       case '-': sym= '_'; break;
+                                                       case '=': sym= '+'; break;
+                                                       case '[': sym= '{'; break;
+                                                       case ']': sym= '}'; break;
+                                                       case '\\': sym= '|'; break;
+                                                       case ';': sym= ':'; break;
+                                                       case '\'': sym= '"'; break;
+                                                       case ',': sym= '<'; break;
+                                                       case '.': sym= '>'; break;
+                                                       case '/': sym= '?'; break;
+                                                       default:            break;
+                                               }
+                                       }
+                               }
+                       }
+
+                       g_event= new GHOST_EventKey(getMilliSeconds(), type, window, gkey, sym);
                }
                break;
        }
index ace6cc0..38f3985 100644 (file)
  * @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
 #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"
+
+#ifdef WITH_INPUT_NDOF
+#include "GHOST_NDOFManagerWin32.h"
+#endif
 
 // Key code values not found in winuser.h
 #ifndef VK_MINUS
 #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 */
+#ifdef WITH_INPUT_NDOF
+#define DEVICE_COUNT 2
+#else
+#define DEVICE_COUNT 1
+#endif
+
+       RAWINPUTDEVICE devices[DEVICE_COUNT];
+       memset(devices, 0, DEVICE_COUNT * sizeof(RAWINPUTDEVICE));
+
+       // Initiates WM_INPUT messages from keyboard
+       // That way GHOST can retrieve true keys
+       devices[0].usUsagePage = 0x01;
+       devices[0].usUsage = 0x06; /* http://msdn.microsoft.com/en-us/windows/hardware/gg487473.aspx */
 
-       return RegisterRawInputDevices(&device, 1, sizeof(device));
-};
+#ifdef WITH_INPUT_NDOF
+       // multi-axis mouse (SpaceNavigator, etc.)
+       devices[1].usUsagePage = 0x01;
+       devices[1].usUsage = 0x08;
+#endif
+
+       if (RegisterRawInputDevices(devices, DEVICE_COUNT, sizeof(RAWINPUTDEVICE)))
+               ; // yay!
+       else
+               printf("could not register for RawInput: %d\n", (int)GetLastError());
+
+#undef DEVICE_COUNT
+}
 
 GHOST_SystemWin32::GHOST_SystemWin32()
 : m_hasPerformanceCounter(false), m_freq(0), m_start(0)
@@ -186,6 +172,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 +234,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 +375,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 +424,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 +705,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 +740,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 +769,95 @@ 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);
+                       // massage into blender view coords (same goes for rotation)
+                       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
+               {
+                       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 +874,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;
+#ifdef WITH_INPUT_NDOF
+                                       case RIM_TYPEHID:
+                                               if (system->processNDOF(raw))
+                                                       eventHandled = true;
+                                               break;
+#endif
                                        }
-                                       break;
+                               break;
+                               }
                                ////////////////////////////////////////////////////////////////////////
                                // Keyboard events, ignored
                                ////////////////////////////////////////////////////////////////////////
@@ -839,9 +915,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 +1065,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 +1203,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 +1224,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 +1298,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
index 729ad56..858312b 100644 (file)
 #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"
 
 #      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,24 @@ 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);
-       
+
+#ifdef WITH_INPUT_NDOF
+       /**
+        * 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);
+#endif
+
        /**
         * Returns the local state of the modifier keys (from the message queue).
         * @param keys The state of the keys.
@@ -412,11 +336,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
@@ -445,15 +364,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 +397,3 @@ inline void GHOST_SystemWin32::handleKeyboardChange(void)
        }
 }
 #endif // _GHOST_SYSTEM_WIN32_H_
-
index dd296fa..d5100e5 100644 (file)
 #include "GHOST_EventKey.h"
 #include "GHOST_EventButton.h"
 #include "GHOST_EventWheel.h"
-#include "GHOST_EventNDOF.h"
-#include "GHOST_NDOFManager.h"
 #include "GHOST_DisplayManagerX11.h"
+#ifdef WITH_INPUT_NDOF
+#include "GHOST_NDOFManagerX11.h"
+#endif
 
 #include "GHOST_Debug.h"
 
 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 +169,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 +266,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 +377,6 @@ lastEventTime(Time default_time) {
     return data.timestamp;
 }
 
-
-
        bool 
 GHOST_SystemX11::
 processEvents(
@@ -428,6 +417,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 +607,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 +640,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 +698,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,18 +817,6 @@ GHOST_SystemX11::processEvent(XEvent *xe)
        }
 }
 
-       void *
-GHOST_SystemX11::
-prepareNdofInfo(volatile GHOST_TEventNDOFData *currentNdofValues)
-{
-       const vector<GHOST_IWindow*>& v(m_windowManager->getWindows());
-       if (v.size() > 0)
-               sNdofInfo.window = static_cast<GHOST_WindowX11*>(v[0])->getXWindow();
-       sNdofInfo.display = m_display;
-       sNdofInfo.currValues = currentNdofValues;
-       return (void*)&sNdofInfo;
-}
-
        GHOST_TSuccess 
 GHOST_SystemX11::
 getModifierKeys(
index 746cd4e..845243f 100644 (file)
@@ -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,
index ef9ebdf..eddff8b 100644 (file)
@@ -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
index 4055c3a..70914d9 100644 (file)
 #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>
index 5aed058..0c5ef69 100644 (file)
@@ -16,7 +16,7 @@
 #
 # ##### END GPL LICENSE BLOCK #####
 
-# <pep8 compliant>
+# <pep8-80 compliant>
 
 __all__ = (
     "paths",
@@ -26,12 +26,13 @@ __all__ = (
     "disable",
     "reset_all",
     "module_bl_info",
-)
+    )
 
 import bpy as _bpy
 
 
 error_duplicates = False
+error_encoding = False
 
 
 def paths():
@@ -51,14 +52,18 @@ def paths():
 
 def modules(module_cache):
     global error_duplicates
+    global error_encoding
     import os
 
     error_duplicates = False
+    error_encoding = False
 
     path_list = paths()
 
     # fake module importing
     def fake_module(mod_name, mod_path, speedy=True):
+        global error_encoding
+
         if _bpy.app.debug:
             print("fake_module", mod_path, mod_name)
         import ast
@@ -69,12 +74,28 @@ def modules(module_cache):
             line_iter = iter(file_mod)
             l = ""
             while not l.startswith("bl_info"):
-                l = line_iter.readline()
+                try:
+                    l = line_iter.readline()
+                except UnicodeDecodeError as e:
+                    if not error_encoding:
+                        error_encoding = True
+                        print("Error reading file as UTF-8:", mod_path, e)
+                    file_mod.close()
+                    return None
+
                 if len(l) == 0:
                     break
             while l.rstrip():
                 lines.append(l)
-                l = line_iter.readline()
+                try:
+                    l = line_iter.readline()
+                except UnicodeDecodeError as e:
+                    if not error_encoding:
+                        error_encoding = True
+                        print("Error reading file as UTF-8:", mod_path, e)
+                    file_mod.close()
+                    return None
+
             data = "".join(lines)
 
         else:
@@ -129,7 +150,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
 
@@ -144,7 +170,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
 
 
@@ -164,8 +192,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
@@ -208,7 +237,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)
@@ -255,8 +285,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
 
@@ -311,7 +342,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
index 0add2b3..a43b42e 100644 (file)
@@ -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
@@ -49,7 +49,8 @@ def _main():
 
     # 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:
index eb1a5ff..284fef9 100644 (file)
 #
 # ##### 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
 
index 57d3e6d..a630437 100644 (file)
 #
 # ##### 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:
index 06d41fa..d853d5f 100644 (file)
@@ -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",
-)
+    )
index e56c1c6..eab75c3 100644 (file)
 #
 # ##### 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, )
 
index 0a3f139..bb4e95c 100644 (file)
@@ -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}
@@ -206,7 +283,8 @@ 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 in {'VERTS', 'FACES'}:
         return False, None
@@ -254,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,12 +379,14 @@ def path_reference(filepath, base_src, base_dst, mode='AUTO', copy_subdir="", co
     is_relative = filepath.startswith("//")
     filepath_abs = os.path.normpath(bpy.path.abspath(filepath, base_src))
 
-    if mode in ('ABSOLUTE', 'RELATIVE', 'STRIP'):
+    if mode in {'ABSOLUTE', 'RELATIVE', 'STRIP'}:
         pass
     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)
@@ -367,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:
@@ -377,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
index ecd620f..c965169 100644 (file)
@@ -26,7 +26,7 @@ __all__ = (
     "edge_loops_from_edges",
     "ngon_tesselate",
     "face_random_points",
-)
+    )
 
 
 def mesh_linked_faces(mesh):
@@ -294,7 +294,7 @@ def ngon_tesselate(from_data, indices, fix_loops=True):
         '''
         Normal single concave loop filling
         '''
-        if type(from_data) in (tuple, list):
+        if type(from_data) in {tuple, list}:
             verts = [Vector(from_data[i]) for ii, i in enumerate(indices)]
         else:
             verts = [from_data.vertices[i].co for ii, i in enumerate(indices)]
@@ -312,7 +312,7 @@ def ngon_tesselate(from_data, indices, fix_loops=True):
         used twice. This is used by lightwave LWO files a lot
         '''
 
-        if type(from_data) in (tuple, list):
+        if type(from_data) in {tuple, list}:
             verts = [vert_treplet(Vector(from_data[i]), ii)
                      for ii, i in enumerate(indices)]
         else:
index 51a8d4b..790f5ba 100644 (file)
 #
 # ##### 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:
index 5796abc..2632563 100644 (file)
 #
 # ##### 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):
@@ -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):
index fdf5172..42d2bf9 100644 (file)
@@ -120,7 +120,7 @@ def fromxml(data):
         py_item = (xml_node.tagName, _fromxml_kwargs(xml_node), [])
         #_fromxml_iter(py_item, xml_node.childNodes)
         for xml_node_child in xml_node.childNodes:
-            if xml_node_child.nodeType not in (xml_node_child.TEXT_NODE, xml_node_child.COMMENT_NODE):
+            if xml_node_child.nodeType not in {xml_node_child.TEXT_NODE, xml_node_child.COMMENT_NODE}:
                 py_item[CHILDREN].append(_fromxml(xml_node_child))
         return py_item
 
index 5df04b8..f4b6de2 100644 (file)
@@ -40,13 +40,13 @@ def _parse_rna(prop, value):
     elif prop.type == 'INT':
         value = int(value)
     elif prop.type == 'BOOLEAN':
-        if value in (True, False):
+        if value in {True, False}:
             pass
         else:
-            if value not in ("True", "False"):
+            if value not in {"True", "False"}:
                 raise Exception("invalid bool value: %s" % value)
             value = bool(value == "True")
-    elif prop.type in ('STRING', 'ENUM'):
+    elif prop.type in {'STRING', 'ENUM'}:
         pass
     elif prop.type == 'POINTER':
         value = eval("_bpy." + value)
index dc61ce2..03400ed 100644 (file)
 #
 # ##### 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
index 93a344f..943f86a 100644 (file)
@@ -148,7 +148,7 @@ class InfoStructRNA:
         import types
         functions = []
         for identifier, attr in self._get_py_visible_attrs():
-            if type(attr) in (types.FunctionType, types.MethodType):
+            if type(attr) in {types.FunctionType, types.MethodType}:
                 functions.append((identifier, attr))
         return functions
 
@@ -156,7 +156,7 @@ class InfoStructRNA:
         import types
         functions = []
         for identifier, attr in self._get_py_visible_attrs():
-            if type(attr) in (types.BuiltinMethodType, types.BuiltinFunctionType):
+            if type(attr) in {types.BuiltinMethodType, types.BuiltinFunctionType}:
                 functions.append((identifier, attr))
         return functions
 
@@ -260,7 +260,7 @@ class InfoPropertyRNA:
             if self.array_length:
                 type_str += " array of %d items" % (self.array_length)
 
-            if self.type in ("float", "int"):
+            if self.type in {"float", "int"}:
                 type_str += " in [%s, %s]" % (range_str(self.min), range_str(self.max))
             elif self.type == "enum":
                 if self.is_enum_flag:
@@ -595,7 +595,7 @@ def BuildRNAInfo():
             for prop in rna_info.properties:
                 # ERROR CHECK
                 default = prop.default
-                if type(default) in (float, int):
+                if type(default) in {float, int}:
                     if default < prop.min or default > prop.max:
                         print("\t %s.%s, %s not in [%s - %s]" % (rna_info.identifier, prop.identifier, default, prop.min, prop.max))