merge with trunk r39216
This commit is contained in:
@@ -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)
|
option(WITH_LZMA "Enable best LZMA compression, (used for pointcache)" ON)
|
||||||
|
|
||||||
# Misc
|
# 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)
|
option(WITH_RAYOPTIMIZATION "Enable use of SIMD (SSE) optimizations for the raytracer" ON)
|
||||||
if(UNIX AND NOT APPLE)
|
if(UNIX AND NOT APPLE)
|
||||||
option(WITH_INSTALL_PORTABLE "Install redistributeable runtime, otherwise install into CMAKE_INSTALL_PREFIX" ON)
|
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()
|
||||||
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
|
# OpenSuse needs lutil, ArchLinux not, for now keep, can avoid by using --as-needed
|
||||||
set(PLATFORM_LINKLIBS "-lutil -lc -lm -lpthread -lstdc++")
|
set(PLATFORM_LINKLIBS "-lutil -lc -lm -lpthread -lstdc++")
|
||||||
|
|
||||||
@@ -896,28 +910,15 @@ elseif(APPLE)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(WITH_PYTHON)
|
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
|
# 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_INCLUDE_DIR "${LIBDIR}/python/include/python${PYTHON_VERSION}")
|
||||||
# set(PYTHON_BINARY "${LIBDIR}/python/bin/python${PYTHON_VERSION}") # not used yet
|
# set(PYTHON_BINARY "${LIBDIR}/python/bin/python${PYTHON_VERSION}") # not used yet
|
||||||
set(PYTHON_LIBRARY python${PYTHON_VERSION})
|
set(PYTHON_LIBRARY python${PYTHON_VERSION})
|
||||||
set(PYTHON_LIBPATH "${LIBDIR}/python/lib/python${PYTHON_VERSION}")
|
set(PYTHON_LIBPATH "${LIBDIR}/python/lib/python${PYTHON_VERSION}")
|
||||||
# set(PYTHON_LINKFLAGS "-u _PyMac_Error") # won't build with this enabled
|
# 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()
|
|
||||||
|
|
||||||
# uncached vars
|
# uncached vars
|
||||||
set(PYTHON_INCLUDE_DIRS "${PYTHON_INCLUDE_DIR}")
|
set(PYTHON_INCLUDE_DIRS "${PYTHON_INCLUDE_DIR}")
|
||||||
@@ -972,7 +973,17 @@ elseif(APPLE)
|
|||||||
set(SAMPLERATE_LIBPATH ${SAMPLERATE}/lib)
|
set(SAMPLERATE_LIBPATH ${SAMPLERATE}/lib)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
find_library(SYSTEMSTUBS_LIBRARY
|
||||||
|
NAMES
|
||||||
|
SystemStubs
|
||||||
|
PATHS
|
||||||
|
)
|
||||||
|
mark_as_advanced(SYSTEMSTUBS_LIBRARY)
|
||||||
|
if(SYSTEMSTUBS_LIBRARY)
|
||||||
set(PLATFORM_LINKLIBS stdc++ SystemStubs)
|
set(PLATFORM_LINKLIBS stdc++ SystemStubs)
|
||||||
|
else()
|
||||||
|
set(PLATFORM_LINKLIBS stdc++)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(WITH_COCOA)
|
if(WITH_COCOA)
|
||||||
set(PLATFORM_CFLAGS "-pipe -funsigned-char -DGHOST_COCOA")
|
set(PLATFORM_CFLAGS "-pipe -funsigned-char -DGHOST_COCOA")
|
||||||
@@ -987,9 +998,28 @@ elseif(APPLE)
|
|||||||
elseif(WITH_CODEC_QUICKTIME)
|
elseif(WITH_CODEC_QUICKTIME)
|
||||||
set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -framework QuickTime")
|
set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -framework QuickTime")
|
||||||
endif()
|
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()
|
else()
|
||||||
set(PLATFORM_CFLAGS "-pipe -funsigned-char")
|
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(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()
|
endif()
|
||||||
|
|
||||||
if(WITH_OPENCOLLADA)
|
if(WITH_OPENCOLLADA)
|
||||||
@@ -1029,6 +1059,10 @@ elseif(APPLE)
|
|||||||
set(TIFF_LIBPATH ${TIFF}/lib)
|
set(TIFF_LIBPATH ${TIFF}/lib)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (WITH_INPUT_NDOF)
|
||||||
|
# linker needs "-weak_framework 3DconnexionClient"
|
||||||
|
endif()
|
||||||
|
|
||||||
set(EXETYPE MACOSX_BUNDLE)
|
set(EXETYPE MACOSX_BUNDLE)
|
||||||
|
|
||||||
set(CMAKE_C_FLAGS_DEBUG "-fno-strict-aliasing -g")
|
set(CMAKE_C_FLAGS_DEBUG "-fno-strict-aliasing -g")
|
||||||
@@ -1054,20 +1088,34 @@ if(APPLE OR WIN32)
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# See TEST_SSE_SUPPORT() for how this is defined.
|
||||||
|
|
||||||
if(WITH_RAYOPTIMIZATION)
|
if(WITH_RAYOPTIMIZATION)
|
||||||
if(CMAKE_COMPILER_IS_GNUCC)
|
if(CMAKE_COMPILER_IS_GNUCC)
|
||||||
|
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)
|
if(SUPPORT_SSE_BUILD)
|
||||||
set(PLATFORM_CFLAGS " -msse ${PLATFORM_CFLAGS}")
|
set(PLATFORM_CFLAGS " ${_sse} ${PLATFORM_CFLAGS}")
|
||||||
add_definitions(-D__SSE__ -D__MMX__)
|
add_definitions(-D__SSE__ -D__MMX__)
|
||||||
endif()
|
endif()
|
||||||
if(SUPPORT_SSE2_BUILD)
|
if(SUPPORT_SSE2_BUILD)
|
||||||
set(PLATFORM_CFLAGS " -msse2 ${PLATFORM_CFLAGS}")
|
set(PLATFORM_CFLAGS " ${_sse2} ${PLATFORM_CFLAGS}")
|
||||||
add_definitions(-D__SSE2__)
|
add_definitions(-D__SSE2__)
|
||||||
if(NOT SUPPORT_SSE_BUILD) # dont double up
|
if(NOT SUPPORT_SSE_BUILD) # dont double up
|
||||||
add_definitions(-D__MMX__)
|
add_definitions(-D__MMX__)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
endif()
|
unset(_sse)
|
||||||
|
unset(_sse2)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(WITH_IMAGE_OPENJPEG)
|
if(WITH_IMAGE_OPENJPEG)
|
||||||
@@ -1306,6 +1354,7 @@ if(FIRST_RUN)
|
|||||||
info_cfg_option(WITH_OPENCOLLADA)
|
info_cfg_option(WITH_OPENCOLLADA)
|
||||||
info_cfg_option(WITH_FFTW3)
|
info_cfg_option(WITH_FFTW3)
|
||||||
info_cfg_option(WITH_INTERNATIONAL)
|
info_cfg_option(WITH_INTERNATIONAL)
|
||||||
|
info_cfg_option(WITH_INPUT_NDOF)
|
||||||
|
|
||||||
info_cfg_text("Compiler Options:")
|
info_cfg_text("Compiler Options:")
|
||||||
info_cfg_option(WITH_BUILDINFO)
|
info_cfg_option(WITH_BUILDINFO)
|
||||||
|
29
SConstruct
29
SConstruct
@@ -111,6 +111,11 @@ btools.print_targets(B.targets, B.bc)
|
|||||||
|
|
||||||
# handling cmd line arguments & config file
|
# 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
|
# first check cmdline for toolset and we create env to work on
|
||||||
quickie = B.arguments.get('BF_QUICK', None)
|
quickie = B.arguments.get('BF_QUICK', None)
|
||||||
quickdebug = B.arguments.get('BF_QUICKDEBUG', 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_BUILDINFO'] = False
|
||||||
target_env_defs['BF_NO_ELBEEM'] = True
|
target_env_defs['BF_NO_ELBEEM'] = True
|
||||||
target_env_defs['WITH_BF_PYTHON'] = False
|
target_env_defs['WITH_BF_PYTHON'] = False
|
||||||
|
target_env_defs['WITH_BF_3DMOUSE'] = False
|
||||||
|
|
||||||
# Merge blenderlite, let command line to override
|
# Merge blenderlite, let command line to override
|
||||||
for k,v in target_env_defs.iteritems():
|
for k,v in target_env_defs.iteritems():
|
||||||
if k not in B.arguments:
|
if k not in B.arguments:
|
||||||
env[k] = v
|
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['WITH_BF_OPENMP'] == 1:
|
||||||
if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
|
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')
|
dllsources.append('${LCGDIR}/sndfile/lib/libsndfile-1.dll')
|
||||||
|
|
||||||
if env['WITH_BF_FFMPEG']:
|
if env['WITH_BF_FFMPEG']:
|
||||||
dllsources += ['${BF_FFMPEG_LIBPATH}/avcodec-52.dll',
|
dllsources += env['BF_FFMPEG_DLL'].split()
|
||||||
'${BF_FFMPEG_LIBPATH}/avformat-52.dll',
|
|
||||||
'${BF_FFMPEG_LIBPATH}/avdevice-52.dll',
|
|
||||||
'${BF_FFMPEG_LIBPATH}/avutil-50.dll',
|
|
||||||
'${BF_FFMPEG_LIBPATH}/swscale-0.dll']
|
|
||||||
|
|
||||||
# Since the thumb handler is loaded by Explorer, architecture is
|
# Since the thumb handler is loaded by Explorer, architecture is
|
||||||
# strict: the x86 build fails on x64 Windows. We need to ship
|
# strict: the x86 build fails on x64 Windows. We need to ship
|
||||||
|
@@ -22,7 +22,7 @@ BF_EXPAT_LIB = ''
|
|||||||
WITH_BF_FFMPEG = True
|
WITH_BF_FFMPEG = True
|
||||||
WITH_BF_STATICFFMPEG = 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_LIBPATH = '${BF_FFMPEG}/lib32'
|
||||||
BF_FFMPEG_LIB_STATIC = '${BF_FFMPEG_LIBPATH}/libavformat.a ${BF_FFMPEG_LIBPATH}/libswscale.a ' + \
|
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}/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 = '/home/sources/staticlibs/jemalloc'
|
||||||
BF_JEMALLOC_LIBPATH = '${BF_JEMALLOC}/lib32'
|
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
|
# Compilation and optimization
|
||||||
BF_DEBUG = False
|
BF_DEBUG = False
|
||||||
REL_CFLAGS = ['-O2']
|
REL_CFLAGS = ['-O2']
|
||||||
|
@@ -13,7 +13,18 @@ WITH_BF_STATICPYTHON = True
|
|||||||
WITH_BF_COLLADA = False
|
WITH_BF_COLLADA = False
|
||||||
|
|
||||||
# FFMPEG configuration
|
# 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++
|
# Don't depend on system's libstdc++
|
||||||
WITH_BF_STATICCXX = True
|
WITH_BF_STATICCXX = True
|
||||||
@@ -65,6 +76,12 @@ WITH_BF_STATICJEMALLOC = True
|
|||||||
BF_JEMALLOC = '/home/sources/staticlibs/jemalloc'
|
BF_JEMALLOC = '/home/sources/staticlibs/jemalloc'
|
||||||
BF_JEMALLOC_LIBPATH = '${BF_JEMALLOC}/lib32'
|
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
|
# Compilation and optimization
|
||||||
BF_DEBUG = False
|
BF_DEBUG = False
|
||||||
REL_CFLAGS = ['-O2']
|
REL_CFLAGS = ['-O2']
|
||||||
|
@@ -13,7 +13,18 @@ WITH_BF_STATICPYTHON = True
|
|||||||
WITH_BF_COLLADA = False
|
WITH_BF_COLLADA = False
|
||||||
|
|
||||||
# FFMPEG configuration
|
# 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++
|
# Don't depend on system's libstdc++
|
||||||
WITH_BF_STATICCXX = True
|
WITH_BF_STATICCXX = True
|
||||||
@@ -65,6 +76,12 @@ WITH_BF_STATICJEMALLOC = True
|
|||||||
BF_JEMALLOC = '/home/sources/staticlibs/jemalloc'
|
BF_JEMALLOC = '/home/sources/staticlibs/jemalloc'
|
||||||
BF_JEMALLOC_LIBPATH = '${BF_JEMALLOC}/lib64'
|
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
|
# Compilation and optimization
|
||||||
BF_DEBUG = False
|
BF_DEBUG = False
|
||||||
REL_CFLAGS = ['-O2']
|
REL_CFLAGS = ['-O2']
|
||||||
|
@@ -22,7 +22,7 @@ BF_EXPAT_LIB = ''
|
|||||||
WITH_BF_FFMPEG = True
|
WITH_BF_FFMPEG = True
|
||||||
WITH_BF_STATICFFMPEG = 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_LIBPATH = '${BF_FFMPEG}/lib64'
|
||||||
BF_FFMPEG_LIB_STATIC = '${BF_FFMPEG_LIBPATH}/libavformat.a ${BF_FFMPEG_LIBPATH}/libswscale.a ' + \
|
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}/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 = '/home/sources/staticlibs/jemalloc'
|
||||||
BF_JEMALLOC_LIBPATH = '${BF_JEMALLOC}/lib64'
|
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
|
# Compilation and optimization
|
||||||
BF_DEBUG = False
|
BF_DEBUG = False
|
||||||
REL_CFLAGS = ['-O2']
|
REL_CFLAGS = ['-O2']
|
||||||
|
@@ -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, 'salad_linux_x86_64_scons', '', generic_builder, 'soc-2011-salad')
|
||||||
add_builder(c, 'win32_scons', 'windows', generic_builder)
|
add_builder(c, 'win32_scons', 'windows', generic_builder)
|
||||||
add_builder(c, 'salad_win32_scons', 'windows', generic_builder, 'soc-2011-salad')
|
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_i386_cmake', '', generic_builder)
|
||||||
#add_builder(c, 'freebsd_x86_64_cmake', '', generic_builder)
|
#add_builder(c, 'freebsd_x86_64_cmake', '', generic_builder)
|
||||||
|
|
||||||
|
@@ -108,5 +108,33 @@ else:
|
|||||||
|
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
else:
|
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)
|
retcode = subprocess.call(['python', 'scons/scons.py'] + scons_options)
|
||||||
sys.exit(retcode)
|
sys.exit(retcode)
|
||||||
|
@@ -72,6 +72,34 @@ if builder.find('scons') != -1:
|
|||||||
retcode = subprocess.call(['python', 'scons/scons.py'] + scons_options)
|
retcode = subprocess.call(['python', 'scons/scons.py'] + scons_options)
|
||||||
sys.exit(retcode)
|
sys.exit(retcode)
|
||||||
else:
|
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)
|
retcode = subprocess.call(['python', 'scons/scons.py'] + scons_options)
|
||||||
sys.exit(retcode)
|
sys.exit(retcode)
|
||||||
|
|
||||||
|
70
build_files/cmake/Modules/FindSpacenav.cmake
Normal file
70
build_files/cmake/Modules/FindSpacenav.cmake
Normal file
@@ -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
|
||||||
|
)
|
@@ -30,7 +30,18 @@ Example linux usage
|
|||||||
Windows not supported so far
|
Windows not supported so far
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from project_info import *
|
from project_info import (SIMPLE_PROJECTFILE,
|
||||||
|
SOURCE_DIR,
|
||||||
|
CMAKE_DIR,
|
||||||
|
PROJECT_DIR,
|
||||||
|
source_list,
|
||||||
|
is_project_file,
|
||||||
|
is_c_header,
|
||||||
|
# is_py,
|
||||||
|
cmake_advanced_info,
|
||||||
|
cmake_compiler_defines,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
from os.path import join, dirname, normpath, relpath, exists
|
from os.path import join, dirname, normpath, relpath, exists
|
||||||
|
@@ -31,7 +31,17 @@ example linux usage
|
|||||||
python .~/blenderSVN/blender/build_files/cmake/cmake_qtcreator_project.py ~/blenderSVN/cmake
|
python .~/blenderSVN/blender/build_files/cmake/cmake_qtcreator_project.py ~/blenderSVN/cmake
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from project_info import *
|
from project_info import (SIMPLE_PROJECTFILE,
|
||||||
|
SOURCE_DIR,
|
||||||
|
# CMAKE_DIR,
|
||||||
|
PROJECT_DIR,
|
||||||
|
source_list,
|
||||||
|
is_project_file,
|
||||||
|
is_c_header,
|
||||||
|
is_py,
|
||||||
|
cmake_advanced_info,
|
||||||
|
cmake_compiler_defines,
|
||||||
|
)
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
@@ -62,6 +62,10 @@ macro(blender_include_dirs
|
|||||||
foreach(_INC ${ARGV})
|
foreach(_INC ${ARGV})
|
||||||
get_filename_component(_ABS_INC ${_INC} ABSOLUTE)
|
get_filename_component(_ABS_INC ${_INC} ABSOLUTE)
|
||||||
list(APPEND _ALL_INCS ${_ABS_INC})
|
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()
|
endforeach()
|
||||||
include_directories(${_ALL_INCS})
|
include_directories(${_ALL_INCS})
|
||||||
unset(_INC)
|
unset(_INC)
|
||||||
@@ -75,6 +79,9 @@ macro(blender_include_dirs_sys
|
|||||||
foreach(_INC ${ARGV})
|
foreach(_INC ${ARGV})
|
||||||
get_filename_component(_ABS_INC ${_INC} ABSOLUTE)
|
get_filename_component(_ABS_INC ${_INC} ABSOLUTE)
|
||||||
list(APPEND _ALL_INCS ${_ABS_INC})
|
list(APPEND _ALL_INCS ${_ABS_INC})
|
||||||
|
##if(NOT EXISTS "${_ABS_INC}/")
|
||||||
|
## message(FATAL_ERROR "Include not found: ${_ABS_INC}/")
|
||||||
|
##endif()
|
||||||
endforeach()
|
endforeach()
|
||||||
include_directories(SYSTEM ${_ALL_INCS})
|
include_directories(SYSTEM ${_ALL_INCS})
|
||||||
unset(_INC)
|
unset(_INC)
|
||||||
@@ -314,6 +321,10 @@ macro(setup_liblinks
|
|||||||
if(WITH_MEM_JEMALLOC)
|
if(WITH_MEM_JEMALLOC)
|
||||||
target_link_libraries(${target} ${JEMALLOC_LIBRARIES})
|
target_link_libraries(${target} ${JEMALLOC_LIBRARIES})
|
||||||
endif()
|
endif()
|
||||||
|
if(WITH_INPUT_NDOF)
|
||||||
|
target_link_libraries(${target} ${NDOF_LIBRARIES})
|
||||||
|
endif()
|
||||||
|
|
||||||
if(WIN32 AND NOT UNIX)
|
if(WIN32 AND NOT UNIX)
|
||||||
target_link_libraries(${target} ${PTHREADS_LIBRARIES})
|
target_link_libraries(${target} ${PTHREADS_LIBRARIES})
|
||||||
endif()
|
endif()
|
||||||
|
@@ -21,14 +21,23 @@ cmd = 'uname -p'
|
|||||||
MAC_PROC=commands.getoutput(cmd)
|
MAC_PROC=commands.getoutput(cmd)
|
||||||
cmd = 'uname -r'
|
cmd = 'uname -r'
|
||||||
cmd_res=commands.getoutput(cmd)
|
cmd_res=commands.getoutput(cmd)
|
||||||
if cmd_res[0]=='7':
|
|
||||||
|
if cmd_res[:1]=='7':
|
||||||
MAC_CUR_VER='10.3'
|
MAC_CUR_VER='10.3'
|
||||||
elif cmd_res[0]=='8':
|
elif cmd_res[:1]=='8':
|
||||||
MAC_CUR_VER='10.4'
|
MAC_CUR_VER='10.4'
|
||||||
elif cmd_res[0]=='9':
|
elif cmd_res[:1]=='9':
|
||||||
MAC_CUR_VER='10.5'
|
MAC_CUR_VER='10.5'
|
||||||
elif cmd_res[0]=='10':
|
elif cmd_res[:2]=='10':
|
||||||
MAC_CUR_VER='10.6'
|
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':
|
if MACOSX_ARCHITECTURE == 'x86_64' or MACOSX_ARCHITECTURE == 'ppc64':
|
||||||
USE_QTKIT=True # Carbon quicktime is not available for 64bit
|
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
|
# Default target OSX settings per architecture
|
||||||
# Can be customized
|
# Can be customized
|
||||||
|
|
||||||
if MACOSX_ARCHITECTURE == 'ppc':
|
if MACOSX_ARCHITECTURE == 'ppc' and MAC_CUR_VER == '10.4':
|
||||||
# ppc release are now made for 10.4
|
# all releases are now made for 10.5 !
|
||||||
# MAC_MIN_VERS = '10.3'
|
# MAC_MIN_VERS = '10.3'
|
||||||
# MACOSX_SDK='/Developer/SDKs/MacOSX10.3.9.sdk'
|
# MACOSX_SDK='/Developer/SDKs/MacOSX10.3.9.sdk'
|
||||||
# LCGDIR = '#../lib/darwin-6.1-powerpc'
|
# LCGDIR = '#../lib/darwin-6.1-powerpc'
|
||||||
@@ -50,7 +59,7 @@ if MACOSX_ARCHITECTURE == 'ppc':
|
|||||||
LCGDIR = '#../lib/darwin-8.0.0-powerpc'
|
LCGDIR = '#../lib/darwin-8.0.0-powerpc'
|
||||||
CC = 'gcc-4.0'
|
CC = 'gcc-4.0'
|
||||||
CXX = 'g++-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'
|
MAC_MIN_VERS = '10.4'
|
||||||
MACOSX_DEPLOYMENT_TARGET = '10.4'
|
MACOSX_DEPLOYMENT_TARGET = '10.4'
|
||||||
MACOSX_SDK='/Developer/SDKs/MacOSX10.4u.sdk'
|
MACOSX_SDK='/Developer/SDKs/MacOSX10.4u.sdk'
|
||||||
@@ -58,12 +67,22 @@ elif MACOSX_ARCHITECTURE == 'i386':
|
|||||||
CC = 'gcc-4.0'
|
CC = 'gcc-4.0'
|
||||||
CXX = 'g++-4.0'
|
CXX = 'g++-4.0'
|
||||||
else :
|
else :
|
||||||
|
if 'Mac OS X 10.5' in MACOSX_SDK_CHECK:
|
||||||
|
# OSX 10.5/6 with Xcode 3.x
|
||||||
MAC_MIN_VERS = '10.5'
|
MAC_MIN_VERS = '10.5'
|
||||||
MACOSX_DEPLOYMENT_TARGET = '10.5'
|
MACOSX_DEPLOYMENT_TARGET = '10.5'
|
||||||
MACOSX_SDK='/Developer/SDKs/MacOSX10.5.sdk'
|
MACOSX_SDK='/Developer/SDKs/MacOSX10.5.sdk'
|
||||||
LCGDIR = '#../lib/darwin-9.x.universal'
|
LCGDIR = '#../lib/darwin-9.x.universal'
|
||||||
CC = 'gcc-4.2'
|
CC = 'gcc-4.2'
|
||||||
CXX = 'g++-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}'
|
LIBDIR = '${LCGDIR}'
|
||||||
|
|
||||||
@@ -71,8 +90,8 @@ LIBDIR = '${LCGDIR}'
|
|||||||
################### Dependency settings ##################
|
################### Dependency settings ##################
|
||||||
#############################################################################
|
#############################################################################
|
||||||
|
|
||||||
#Defaults openMP to true if compiler (currently only gcc 4.2) handles it
|
#Defaults openMP to true if compiler handles it
|
||||||
if CC == 'gcc-4.2':
|
if CC == 'gcc-4.2' or CC == 'llvm-gcc-4.2':
|
||||||
WITH_BF_OPENMP = True # multithreading for fluids, cloth and smoke
|
WITH_BF_OPENMP = True # multithreading for fluids, cloth and smoke
|
||||||
else:
|
else:
|
||||||
WITH_BF_OPENMP = False
|
WITH_BF_OPENMP = False
|
||||||
@@ -188,8 +207,8 @@ BF_GETTEXT_INC = '${BF_GETTEXT}/include'
|
|||||||
BF_GETTEXT_LIB = 'intl'
|
BF_GETTEXT_LIB = 'intl'
|
||||||
BF_GETTEXT_LIBPATH = '${BF_GETTEXT}/lib'
|
BF_GETTEXT_LIBPATH = '${BF_GETTEXT}/lib'
|
||||||
|
|
||||||
WITH_BF_GAMEENGINE=True
|
WITH_BF_GAMEENGINE = True
|
||||||
WITH_BF_PLAYER = False
|
WITH_BF_PLAYER = True
|
||||||
|
|
||||||
WITH_BF_BULLET = True
|
WITH_BF_BULLET = True
|
||||||
BF_BULLET = '#extern/bullet2/src'
|
BF_BULLET = '#extern/bullet2/src'
|
||||||
@@ -240,7 +259,7 @@ BF_OPENGL_LIBPATH = '/System/Library/Frameworks/OpenGL.framework/Libraries'
|
|||||||
BF_OPENGL_LINKFLAGS = ['-framework', 'OpenGL']
|
BF_OPENGL_LINKFLAGS = ['-framework', 'OpenGL']
|
||||||
|
|
||||||
#OpenCollada flags
|
#OpenCollada flags
|
||||||
WITH_BF_COLLADA = False
|
WITH_BF_COLLADA = True
|
||||||
BF_COLLADA = '#source/blender/collada'
|
BF_COLLADA = '#source/blender/collada'
|
||||||
BF_COLLADA_INC = '${BF_COLLADA}'
|
BF_COLLADA_INC = '${BF_COLLADA}'
|
||||||
BF_COLLADA_LIB = 'bf_collada'
|
BF_COLLADA_LIB = 'bf_collada'
|
||||||
@@ -265,6 +284,8 @@ if MACOSX_ARCHITECTURE == 'i386':
|
|||||||
elif MACOSX_ARCHITECTURE == 'x86_64':
|
elif MACOSX_ARCHITECTURE == 'x86_64':
|
||||||
BF_RAYOPTIMIZATION_SSE_FLAGS = ['-msse','-msse2']
|
BF_RAYOPTIMIZATION_SSE_FLAGS = ['-msse','-msse2']
|
||||||
|
|
||||||
|
# SpaceNavigator and related 3D mice
|
||||||
|
WITH_BF_3DMOUSE = True
|
||||||
|
|
||||||
#############################################################################
|
#############################################################################
|
||||||
################### various compile settings and flags ##################
|
################### various compile settings and flags ##################
|
||||||
@@ -283,28 +304,31 @@ CPPFLAGS = []+ARCH_FLAGS
|
|||||||
CCFLAGS = ['-pipe','-funsigned-char']+ARCH_FLAGS
|
CCFLAGS = ['-pipe','-funsigned-char']+ARCH_FLAGS
|
||||||
CXXFLAGS = ['-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
|
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:
|
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
|
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 WITH_BF_QUICKTIME:
|
||||||
if USE_QTKIT == True:
|
if USE_QTKIT:
|
||||||
PLATFORM_LINKFLAGS = PLATFORM_LINKFLAGS+['-framework','QTKit']
|
PLATFORM_LINKFLAGS = PLATFORM_LINKFLAGS+['-framework','QTKit']
|
||||||
else:
|
else:
|
||||||
PLATFORM_LINKFLAGS = PLATFORM_LINKFLAGS+['-framework','QuickTime']
|
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
|
#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']
|
LLIBS = ['stdc++', 'SystemStubs']
|
||||||
|
|
||||||
# some flags shuffling for different Os versions
|
# some flags shuffling for different OS versions
|
||||||
if MAC_MIN_VERS == '10.3':
|
if MAC_MIN_VERS == '10.3':
|
||||||
CFLAGS = ['-fuse-cxa-atexit']+CFLAGS
|
CFLAGS = ['-fuse-cxa-atexit']+CFLAGS
|
||||||
CXXFLAGS = ['-fuse-cxa-atexit']+CXXFLAGS
|
CXXFLAGS = ['-fuse-cxa-atexit']+CXXFLAGS
|
||||||
PLATFORM_LINKFLAGS = ['-fuse-cxa-atexit']+PLATFORM_LINKFLAGS
|
PLATFORM_LINKFLAGS = ['-fuse-cxa-atexit']+PLATFORM_LINKFLAGS
|
||||||
LLIBS.append('crt3.o')
|
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]
|
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
|
PLATFORM_LINKFLAGS = ['-mmacosx-version-min='+MAC_MIN_VERS,'-Wl','-isysroot',MACOSX_SDK,'-arch',MACOSX_ARCHITECTURE]+PLATFORM_LINKFLAGS
|
||||||
CCFLAGS=SDK_FLAGS+CCFLAGS
|
CCFLAGS=SDK_FLAGS+CCFLAGS
|
||||||
|
@@ -192,6 +192,14 @@ WITH_BF_OPENMP = True
|
|||||||
WITH_BF_RAYOPTIMIZATION = True
|
WITH_BF_RAYOPTIMIZATION = True
|
||||||
BF_RAYOPTIMIZATION_SSE_FLAGS = ['-msse','-pthread']
|
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'
|
CC = 'gcc'
|
||||||
CXX = 'g++'
|
CXX = 'g++'
|
||||||
|
@@ -7,6 +7,7 @@ BF_FFMPEG = LIBDIR +'/ffmpeg'
|
|||||||
BF_FFMPEG_INC = '${BF_FFMPEG}/include ${BF_FFMPEG}/include/msvc'
|
BF_FFMPEG_INC = '${BF_FFMPEG}/include ${BF_FFMPEG}/include/msvc'
|
||||||
BF_FFMPEG_LIBPATH='${BF_FFMPEG}/lib'
|
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_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 = LIBDIR + '/python'
|
||||||
BF_PYTHON_VERSION = '3.2'
|
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_LIB = 'OpenCOLLADAStreamWriter OpenCOLLADASaxFrameworkLoader OpenCOLLADAFramework OpenCOLLADABaseUtils GeneratedSaxParser MathMLSolver xml2 pcre buffer ftoa UTF'
|
||||||
BF_OPENCOLLADA_LIBPATH = '${BF_OPENCOLLADA}/lib'
|
BF_OPENCOLLADA_LIBPATH = '${BF_OPENCOLLADA}/lib'
|
||||||
|
|
||||||
|
WITH_BF_3DMOUSE = True
|
||||||
|
|
||||||
#Ray trace optimization
|
#Ray trace optimization
|
||||||
WITH_BF_RAYOPTIMIZATION = True
|
WITH_BF_RAYOPTIMIZATION = True
|
||||||
BF_RAYOPTIMIZATION_SSE_FLAGS = ['/arch:SSE']
|
BF_RAYOPTIMIZATION_SSE_FLAGS = ['/arch:SSE']
|
||||||
|
@@ -7,6 +7,7 @@ BF_FFMPEG = LIBDIR +'/ffmpeg'
|
|||||||
BF_FFMPEG_INC = '${BF_FFMPEG}/include ${BF_FFMPEG}/include/msvc '
|
BF_FFMPEG_INC = '${BF_FFMPEG}/include ${BF_FFMPEG}/include/msvc '
|
||||||
BF_FFMPEG_LIBPATH='${BF_FFMPEG}/lib'
|
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_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 = LIBDIR + '/python'
|
||||||
BF_PYTHON_VERSION = '3.2'
|
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_LIB = 'OpenCOLLADAStreamWriter OpenCOLLADASaxFrameworkLoader OpenCOLLADAFramework OpenCOLLADABaseUtils GeneratedSaxParser MathMLSolver xml2 pcre buffer ftoa UTF'
|
||||||
BF_OPENCOLLADA_LIBPATH = '${BF_OPENCOLLADA}/lib'
|
BF_OPENCOLLADA_LIBPATH = '${BF_OPENCOLLADA}/lib'
|
||||||
|
|
||||||
|
WITH_BF_3DMOUSE = True
|
||||||
|
|
||||||
#Ray trace optimization
|
#Ray trace optimization
|
||||||
WITH_BF_RAYOPTIMIZATION = True
|
WITH_BF_RAYOPTIMIZATION = True
|
||||||
BF_RAYOPTIMIZATION_SSE_FLAGS = ['/arch:SSE','/arch:SSE2']
|
BF_RAYOPTIMIZATION_SSE_FLAGS = ['/arch:SSE','/arch:SSE2']
|
||||||
|
@@ -206,6 +206,12 @@ def setup_staticlibs(lenv):
|
|||||||
if lenv['WITH_BF_STATICJEMALLOC']:
|
if lenv['WITH_BF_STATICJEMALLOC']:
|
||||||
statlibs += Split(lenv['BF_JEMALLOC_LIB_STATIC'])
|
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
|
return statlibs, libincs
|
||||||
|
|
||||||
def setup_syslibs(lenv):
|
def setup_syslibs(lenv):
|
||||||
@@ -271,6 +277,11 @@ def setup_syslibs(lenv):
|
|||||||
if not lenv['WITH_BF_STATICJEMALLOC']:
|
if not lenv['WITH_BF_STATICJEMALLOC']:
|
||||||
syslibs += Split(lenv['BF_JEMALLOC_LIB'])
|
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']
|
syslibs += lenv['LLIBS']
|
||||||
|
|
||||||
return syslibs
|
return syslibs
|
||||||
|
@@ -87,7 +87,7 @@ def validate_arguments(args, bc):
|
|||||||
'BF_PTHREADS', 'BF_PTHREADS_INC', 'BF_PTHREADS_LIB', 'BF_PTHREADS_LIBPATH',
|
'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_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_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_STATICFFMPEG', 'BF_FFMPEG_LIB_STATIC',
|
||||||
'WITH_BF_OGG', 'BF_OGG', 'BF_OGG_LIB',
|
'WITH_BF_OGG', 'BF_OGG', 'BF_OGG_LIB',
|
||||||
'WITH_BF_JPEG', 'BF_JPEG', 'BF_JPEG_INC', 'BF_JPEG_LIB', 'BF_JPEG_LIBPATH',
|
'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',
|
'BF_NO_ELBEEM',
|
||||||
'WITH_BF_CXX_GUARDEDALLOC',
|
'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',
|
'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
|
# 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_PROFILE_CFLAGS', 'BF_PROFILE_CCFLAGS', 'BF_PROFILE_CXXFLAGS', 'BF_PROFILE_LINKFLAGS',
|
||||||
'BF_DEBUG_CFLAGS', 'BF_DEBUG_CCFLAGS', 'BF_DEBUG_CXXFLAGS',
|
'BF_DEBUG_CFLAGS', 'BF_DEBUG_CCFLAGS', 'BF_DEBUG_CXXFLAGS',
|
||||||
'C_WARN', 'CC_WARN', 'CXX_WARN',
|
'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_BSC', 'BF_CONFIG',
|
||||||
'BF_PRIORITYLIST', 'BF_BUILDINFO','CC', 'CXX', 'BF_QUICKDEBUG',
|
'BF_PRIORITYLIST', 'BF_BUILDINFO','CC', 'CXX', 'BF_QUICKDEBUG',
|
||||||
'BF_LISTDEBUG', 'LCGDIR', 'BF_X264_CONFIG', 'BF_XVIDCORE_CONFIG',
|
'BF_LISTDEBUG', 'LCGDIR', 'BF_X264_CONFIG', 'BF_XVIDCORE_CONFIG',
|
||||||
'BF_UNIT_TEST']
|
'BF_UNIT_TEST', 'BF_BITNESS']
|
||||||
|
|
||||||
okdict = {}
|
okdict = {}
|
||||||
|
|
||||||
@@ -291,6 +291,7 @@ def read_opts(env, cfg, args):
|
|||||||
(BoolVariable('WITH_BF_FFMPEG', 'Use FFMPEG if true', False)),
|
(BoolVariable('WITH_BF_FFMPEG', 'Use FFMPEG if true', False)),
|
||||||
('BF_FFMPEG', 'FFMPEG base path', ''),
|
('BF_FFMPEG', 'FFMPEG base path', ''),
|
||||||
('BF_FFMPEG_LIB', 'FFMPEG library', ''),
|
('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_EXTRA', 'FFMPEG flags that must be preserved', ''),
|
||||||
|
|
||||||
('BF_FFMPEG_INC', 'FFMPEG includes', ''),
|
('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_PLAYER', 'Build blenderplayer if true', False)),
|
||||||
(BoolVariable('WITH_BF_NOBLENDER', 'Do not build blender 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', []),
|
('CFLAGS', 'C only flags', []),
|
||||||
('CCFLAGS', 'Generic C and C++ flags', []),
|
('CCFLAGS', 'Generic C and C++ flags', []),
|
||||||
('CXXFLAGS', 'C++ only flags', []),
|
('CXXFLAGS', 'C++ only flags', []),
|
||||||
@@ -453,6 +463,8 @@ def read_opts(env, cfg, args):
|
|||||||
('LLIBS', 'Platform libs', []),
|
('LLIBS', 'Platform libs', []),
|
||||||
('PLATFORM_LINKFLAGS', 'Platform linkflags', []),
|
('PLATFORM_LINKFLAGS', 'Platform linkflags', []),
|
||||||
('MACOSX_ARCHITECTURE', 'python_arch.zip select', ''),
|
('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)),
|
(BoolVariable('BF_PROFILE', 'Add profiling information if true', False)),
|
||||||
('BF_PROFILE_CFLAGS', 'C only profiling flags', []),
|
('BF_PROFILE_CFLAGS', 'C only profiling flags', []),
|
||||||
|
@@ -31,7 +31,7 @@ PROJECT_NAME = Blender
|
|||||||
# This could be handy for archiving the generated documentation or
|
# This could be handy for archiving the generated documentation or
|
||||||
# if some version control system is used.
|
# if some version control system is used.
|
||||||
|
|
||||||
PROJECT_NUMBER = "V2.58"
|
PROJECT_NUMBER = "V2.59"
|
||||||
|
|
||||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||||
# for a project that appears at the top of each page and should give viewer
|
# for a project that appears at the top of each page and should give viewer
|
||||||
|
@@ -219,7 +219,7 @@ div.sphinxsidebarwrapper.fixed {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{%- if theme_stickysidebar|tobool %}
|
{%- 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 */
|
to an anchor */
|
||||||
/*
|
/*
|
||||||
div.related {
|
div.related {
|
||||||
|
4
doc/python_api/examples/bge.constraints.py
Executable file → Normal file
4
doc/python_api/examples/bge.constraints.py
Executable file → Normal file
@@ -31,7 +31,7 @@ edge_angle_y = 1.0
|
|||||||
edge_angle_z = 0.0
|
edge_angle_z = 0.0
|
||||||
|
|
||||||
# create an edge constraint
|
# create an edge constraint
|
||||||
constraints.createConstraint( physics_id_1, physics_id_2,
|
constraints.createConstraint(physics_id_1, physics_id_2,
|
||||||
constraint_type,
|
constraint_type,
|
||||||
edge_position_x, edge_position_y, edge_position_z,
|
edge_position_x, edge_position_y, edge_position_z,
|
||||||
edge_angle_x, edge_angle_y, edge_angle_z )
|
edge_angle_x, edge_angle_y, edge_angle_z)
|
||||||
|
2
doc/python_api/examples/bge.texture.1.py
Executable file → Normal file
2
doc/python_api/examples/bge.texture.1.py
Executable file → Normal file
@@ -8,6 +8,7 @@ Controller.
|
|||||||
from bge import logic
|
from bge import logic
|
||||||
from bge import texture
|
from bge import texture
|
||||||
|
|
||||||
|
|
||||||
def createTexture(cont):
|
def createTexture(cont):
|
||||||
"""Create a new Dynamic Texture"""
|
"""Create a new Dynamic Texture"""
|
||||||
object = cont.owner
|
object = cont.owner
|
||||||
@@ -29,6 +30,7 @@ def createTexture(cont):
|
|||||||
logic.texture.source = new_source
|
logic.texture.source = new_source
|
||||||
logic.texture.refresh(False)
|
logic.texture.refresh(False)
|
||||||
|
|
||||||
|
|
||||||
def removeTexture(cont):
|
def removeTexture(cont):
|
||||||
"""Delete the Dynamic Texture, reversing back the final to its original state."""
|
"""Delete the Dynamic Texture, reversing back the final to its original state."""
|
||||||
try:
|
try:
|
||||||
|
0
doc/python_api/examples/bge.texture.py
Executable file → Normal file
0
doc/python_api/examples/bge.texture.py
Executable file → Normal file
7
doc/python_api/examples/blf.py
Executable file → Normal file
7
doc/python_api/examples/blf.py
Executable file → Normal file
@@ -1,6 +1,7 @@
|
|||||||
"""
|
"""
|
||||||
Hello World Text Example
|
Hello World Text Example
|
||||||
++++++++++++++++++++++++
|
++++++++++++++++++++++++
|
||||||
|
|
||||||
Blender Game Engine example of using the blf module. For this module to work we
|
Blender Game Engine example of using the blf module. For this module to work we
|
||||||
need to use the OpenGL wrapper :class:`~bgl` as well.
|
need to use the OpenGL wrapper :class:`~bgl` as well.
|
||||||
"""
|
"""
|
||||||
@@ -11,6 +12,7 @@ from bge import logic
|
|||||||
import bgl
|
import bgl
|
||||||
import blf
|
import blf
|
||||||
|
|
||||||
|
|
||||||
def init():
|
def init():
|
||||||
"""init function - runs once"""
|
"""init function - runs once"""
|
||||||
# create a new font object, use external ttf file
|
# create a new font object, use external ttf file
|
||||||
@@ -20,7 +22,8 @@ def init():
|
|||||||
|
|
||||||
# set the font drawing routine to run every frame
|
# set the font drawing routine to run every frame
|
||||||
scene = logic.getCurrentScene()
|
scene = logic.getCurrentScene()
|
||||||
scene.post_draw=[write]
|
scene.post_draw = [write]
|
||||||
|
|
||||||
|
|
||||||
def write():
|
def write():
|
||||||
"""write on screen"""
|
"""write on screen"""
|
||||||
@@ -36,6 +39,6 @@ def write():
|
|||||||
|
|
||||||
# BLF drawing routine
|
# BLF drawing routine
|
||||||
font_id = logic.font_id
|
font_id = logic.font_id
|
||||||
blf.position(font_id, (width*0.2), (height*0.3), 0)
|
blf.position(font_id, (width * 0.2), (height * 0.3), 0)
|
||||||
blf.size(font_id, 50, 72)
|
blf.size(font_id, 50, 72)
|
||||||
blf.draw(font_id, "Hello World")
|
blf.draw(font_id, "Hello World")
|
||||||
|
238
doc/python_api/rst/bge.constraints.rst
Executable file → Normal file
238
doc/python_api/rst/bge.constraints.rst
Executable file → Normal file
@@ -1,28 +1,51 @@
|
|||||||
|
|
||||||
Game Engine bge.constraints Module
|
Physics Constraints (bge.constraints)
|
||||||
==================================
|
=====================================
|
||||||
|
|
||||||
.. note::
|
.. module:: bge.constraints
|
||||||
This documentation is still very weak, and needs some help!
|
|
||||||
|
|
||||||
.. 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.
|
Creates a constraint.
|
||||||
|
|
||||||
:arg obj1: first object on Constraint
|
:arg physicsid: the physics id of the first object in constraint
|
||||||
:type obj1: :class:'bge.types.KX_GameObject' #I think, there is no error when I use one
|
:type physicsid: int
|
||||||
|
|
||||||
:arg obj2: second object on Constraint
|
:arg physicsid2: the physics id of the second object in constraint
|
||||||
:type obj2: :class:'bge.types.KX_GameObject' #too
|
:type physicsid2: int
|
||||||
|
|
||||||
:arg restLength: #to be filled
|
:arg constrainttype: the type of the constraint. The constraint types are:
|
||||||
:type restLength: float
|
|
||||||
|
|
||||||
:arg restitution: #to be filled
|
- :class:`POINTTOPOINT_CONSTRAINT`
|
||||||
:type restitution: float
|
- :class:`LINEHINGE_CONSTRAINT`
|
||||||
|
- :class:`ANGULAR_CONSTRAINT`
|
||||||
|
- :class:`CONETWIST_CONSTRAINT`
|
||||||
|
- :class:`VEHICLE_CONSTRAINT`
|
||||||
|
|
||||||
:arg damping: #to be filled
|
:type constrainttype: int
|
||||||
:type damping: float
|
|
||||||
|
: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
|
.. attribute:: error
|
||||||
|
|
||||||
@@ -49,7 +72,7 @@ Game Engine bge.constraints Module
|
|||||||
:type constraintId: int
|
:type constraintId: int
|
||||||
|
|
||||||
:return: a vehicle constraint object.
|
:return: a vehicle constraint object.
|
||||||
:rtype: :class:'KX_VehicleWrapper'
|
:rtype: :class:`bge.types.KX_VehicleWrapper`
|
||||||
|
|
||||||
.. function:: removeConstraint(constraintId)
|
.. function:: removeConstraint(constraintId)
|
||||||
|
|
||||||
@@ -60,10 +83,10 @@ Game Engine bge.constraints Module
|
|||||||
|
|
||||||
.. function:: setCcdMode(ccdMode)
|
.. function:: setCcdMode(ccdMode)
|
||||||
|
|
||||||
..note::
|
.. note::
|
||||||
Very experimental, not recommended
|
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.
|
:arg ccdMode: The new CCD mode.
|
||||||
:type ccdMode: int
|
:type ccdMode: int
|
||||||
@@ -73,21 +96,21 @@ Game Engine bge.constraints Module
|
|||||||
.. note::
|
.. note::
|
||||||
Reasonable default is 0.02 (if units are meters)
|
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.
|
:arg breakingTreshold: The new contact breaking treshold.
|
||||||
:type breakingTreshold: float
|
:type breakingTreshold: float
|
||||||
|
|
||||||
.. function:: setDeactivationAngularTreshold(angularTreshold)
|
.. function:: setDeactivationAngularTreshold(angularTreshold)
|
||||||
|
|
||||||
Sets the deactivation angular treshold.
|
Sets the angular velocity treshold.
|
||||||
|
|
||||||
:arg angularTreshold: New deactivation angular treshold.
|
:arg angularTreshold: New deactivation angular treshold.
|
||||||
:type angularTreshold: float
|
:type angularTreshold: float
|
||||||
|
|
||||||
.. function:: setDeactivationLinearTreshold(linearTreshold)
|
.. function:: setDeactivationLinearTreshold(linearTreshold)
|
||||||
|
|
||||||
Sets the deactivation linear treshold.
|
Sets the linear velocity treshold.
|
||||||
|
|
||||||
:arg linearTreshold: New deactivation linear treshold.
|
:arg linearTreshold: New deactivation linear treshold.
|
||||||
:type linearTreshold: float
|
:type linearTreshold: float
|
||||||
@@ -104,21 +127,20 @@ Game Engine bge.constraints Module
|
|||||||
Sets the debug mode.
|
Sets the debug mode.
|
||||||
|
|
||||||
Debug modes:
|
Debug modes:
|
||||||
- No debug: 0
|
- :class:`DBG_NODEBUG`
|
||||||
- Draw wireframe: 1
|
- :class:`DBG_DRAWWIREFRAME`
|
||||||
- Draw Aabb: 2 #What's Aabb?
|
- :class:`DBG_DRAWAABB`
|
||||||
- Draw freatures text: 4
|
- :class:`DBG_DRAWFREATURESTEXT`
|
||||||
- Draw contact points: 8
|
- :class:`DBG_DRAWCONTACTPOINTS`
|
||||||
- No deactivation: 16
|
- :class:`DBG_NOHELPTEXT`
|
||||||
- No help text: 32
|
- :class:`DBG_DRAWTEXT`
|
||||||
- Draw text: 64
|
- :class:`DBG_PROFILETIMINGS`
|
||||||
- Profile timings: 128
|
- :class:`DBG_ENABLESATCOMPARISION`
|
||||||
- Enable sat comparision: 256
|
- :class:`DBG_DISABLEBULLETLCP`
|
||||||
- Disable Bullet LCP: 512
|
- :class:`DBG_ENABLECCD`
|
||||||
- Enable CCD: 1024
|
- :class:`DBG_DRAWCONSTRAINTS`
|
||||||
- Draw Constraints: #(1 << 11) = ?
|
- :class:`DBG_DRAWCONSTRAINTLIMITS`
|
||||||
- Draw Constraint Limits: #(1 << 12) = ?
|
- :class:`DBG_FASTWIREFRAME`
|
||||||
- Fast Wireframe: #(1 << 13) = ?
|
|
||||||
|
|
||||||
:arg mode: The new debug mode.
|
:arg mode: The new debug mode.
|
||||||
:type mode: int
|
:type mode: int
|
||||||
@@ -138,8 +160,11 @@ Game Engine bge.constraints Module
|
|||||||
|
|
||||||
.. function:: setLinearAirDamping(damping)
|
.. function:: setLinearAirDamping(damping)
|
||||||
|
|
||||||
|
.. note::
|
||||||
Not implemented.
|
Not implemented.
|
||||||
|
|
||||||
|
Sets the linear air damping for rigidbodies.
|
||||||
|
|
||||||
.. function:: setNumIterations(numiter)
|
.. function:: setNumIterations(numiter)
|
||||||
|
|
||||||
Sets the number of iterations for an iterative constraint solver.
|
Sets the number of iterations for an iterative constraint solver.
|
||||||
@@ -156,10 +181,10 @@ Game Engine bge.constraints Module
|
|||||||
|
|
||||||
.. function:: setSolverDamping(damping)
|
.. function:: setSolverDamping(damping)
|
||||||
|
|
||||||
..note::
|
.. note::
|
||||||
Very experimental, not recommended
|
Very experimental, not recommended
|
||||||
|
|
||||||
Sets the solver damping.
|
Sets the damper constant of a penalty based solver.
|
||||||
|
|
||||||
:arg damping: New damping for the solver.
|
:arg damping: New damping for the solver.
|
||||||
:type damping: float
|
:type damping: float
|
||||||
@@ -169,7 +194,7 @@ Game Engine bge.constraints Module
|
|||||||
.. note::
|
.. note::
|
||||||
Very experimental, not recommended
|
Very experimental, not recommended
|
||||||
|
|
||||||
Sets the solver tau.
|
Sets the spring constant of a penalty based solver.
|
||||||
|
|
||||||
:arg tau: New tau for the solver.
|
:arg tau: New tau for the solver.
|
||||||
:type tau: float
|
:type tau: float
|
||||||
@@ -189,7 +214,7 @@ Game Engine bge.constraints Module
|
|||||||
.. note::
|
.. note::
|
||||||
Very experimental, not recommended
|
Very experimental, not recommended
|
||||||
|
|
||||||
Sets the sor constant.
|
Sets the successive overrelaxation constant.
|
||||||
|
|
||||||
:arg sor: New sor value.
|
:arg sor: New sor value.
|
||||||
:type sor: float
|
:type sor: float
|
||||||
@@ -197,3 +222,136 @@ Game Engine bge.constraints Module
|
|||||||
.. function:: setUseEpa(epa)
|
.. function:: setUseEpa(epa)
|
||||||
|
|
||||||
Not implemented.
|
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
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
Game Engine bge.events Module
|
Game Keys (bge.events)
|
||||||
=============================
|
======================
|
||||||
|
|
||||||
*****
|
*****
|
||||||
Intro
|
Intro
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
|
|
||||||
Game Engine bge.logic Module
|
Game Logic (bge.logic)
|
||||||
============================
|
======================
|
||||||
|
|
||||||
*****
|
*****
|
||||||
Intro
|
Intro
|
||||||
*****
|
*****
|
||||||
@@ -216,6 +217,12 @@ General functions
|
|||||||
|
|
||||||
Loads a scene into the game engine.
|
Loads a scene into the game engine.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
This function is not effective immediately, the scene is queued
|
||||||
|
and added on the next logic cycle where it will be available
|
||||||
|
from `getSceneList`
|
||||||
|
|
||||||
:arg name: The name of the scene
|
:arg name: The name of the scene
|
||||||
:type name: string
|
:type name: string
|
||||||
:arg overlay: Overlay or underlay (optional)
|
:arg overlay: Overlay or underlay (optional)
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
Game Engine bge.render Module
|
Rasterizer (bge.render)
|
||||||
=============================
|
=======================
|
||||||
|
|
||||||
*****
|
*****
|
||||||
Intro
|
Intro
|
||||||
@@ -16,8 +16,8 @@ Intro
|
|||||||
import bge.render
|
import bge.render
|
||||||
import bge.logic
|
import bge.logic
|
||||||
|
|
||||||
# SCALE sets the speed of motion
|
# scale sets the speed of motion
|
||||||
SCALE=[1, 0.5]
|
scale = 1.0, 0.5
|
||||||
|
|
||||||
co = bge.logic.getCurrentController()
|
co = bge.logic.getCurrentController()
|
||||||
obj = co.getOwner()
|
obj = co.getOwner()
|
||||||
@@ -27,8 +27,8 @@ Intro
|
|||||||
|
|
||||||
# Transform the mouse coordinates to see how far the mouse has moved.
|
# Transform the mouse coordinates to see how far the mouse has moved.
|
||||||
def mousePos():
|
def mousePos():
|
||||||
x = (bge.render.getWindowWidth()/2 - mouse.getXPosition())*SCALE[0]
|
x = (bge.render.getWindowWidth() / 2 - mouse.getXPosition()) * scale[0]
|
||||||
y = (bge.render.getWindowHeight()/2 - mouse.getYPosition())*SCALE[1]
|
y = (bge.render.getWindowHeight() / 2 - mouse.getYPosition()) * scale[1]
|
||||||
return (x, y)
|
return (x, y)
|
||||||
|
|
||||||
pos = mousePos()
|
pos = mousePos()
|
||||||
@@ -43,7 +43,7 @@ Intro
|
|||||||
bge.logic.addActiveActuator(wmotion, True)
|
bge.logic.addActiveActuator(wmotion, True)
|
||||||
|
|
||||||
# Centre the mouse
|
# 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
|
Constants
|
||||||
|
12
doc/python_api/rst/bge.texture.rst
Executable file → Normal file
12
doc/python_api/rst/bge.texture.rst
Executable file → Normal file
@@ -1,10 +1,6 @@
|
|||||||
|
|
||||||
Game Engine bge.texture Module
|
Video Texture (bge.texture)
|
||||||
==============================
|
===========================
|
||||||
|
|
||||||
.. 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.
|
|
||||||
|
|
||||||
*****
|
*****
|
||||||
Intro
|
Intro
|
||||||
@@ -40,6 +36,10 @@ When the texture object is deleted, the new texture is deleted and the old textu
|
|||||||
|
|
||||||
.. module:: bge.texture
|
.. 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])
|
.. class:: VideoFFmpeg(file [, capture=-1, rate=25.0, width=0, height=0])
|
||||||
|
|
||||||
FFmpeg video source
|
FFmpeg video source
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
Game Engine bge.types Module
|
Game Types (bge.types)
|
||||||
=============================
|
======================
|
||||||
|
|
||||||
.. module:: bge.types
|
.. module:: bge.types
|
||||||
|
|
||||||
|
14
doc/python_api/rst/bgl.rst
Executable file → Normal file
14
doc/python_api/rst/bgl.rst
Executable file → Normal file
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
bgl module (OpenGL wrapper)
|
OpenGL Wrapper (bgl)
|
||||||
===========================
|
====================
|
||||||
|
|
||||||
.. module:: bgl
|
.. module:: bgl
|
||||||
|
|
||||||
@@ -15,7 +15,7 @@ collections of tutorials.
|
|||||||
The "red book": "I{OpenGL Programming Guide: The Official Guide to Learning
|
The "red book": "I{OpenGL Programming Guide: The Official Guide to Learning
|
||||||
OpenGL}" and the online NeHe tutorials are two of the best resources.
|
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.
|
You can use the :class:`Image` type to load and set textures.
|
||||||
See :class:`Image.gl_load` and :class:`Image.gl_load`,
|
See :class:`Image.gl_load` and :class:`Image.gl_load`,
|
||||||
for example.
|
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>`_
|
.. seealso:: `OpenGL Docs <http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/begin.html>`_
|
||||||
|
|
||||||
:type mode: Enumerated constant
|
:type mode: Enumerated constant
|
||||||
:arg mode: Specifies the primitive that will be create from vertices between glBegin and
|
:arg mode: Specifies the primitive that will be create from vertices between
|
||||||
glEnd.
|
glBegin and glEnd.
|
||||||
|
|
||||||
|
|
||||||
.. function:: glBindTexture(target, texture):
|
.. function:: glBindTexture(target, texture):
|
||||||
@@ -1848,10 +1848,13 @@ class Buffer:
|
|||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
import bgl
|
import bgl
|
||||||
|
|
||||||
myByteBuffer = bgl.Buffer(bgl.GL_BYTE, [32, 32])
|
myByteBuffer = bgl.Buffer(bgl.GL_BYTE, [32, 32])
|
||||||
bgl.glGetPolygonStipple(myByteBuffer)
|
bgl.glGetPolygonStipple(myByteBuffer)
|
||||||
|
|
||||||
print(myByteBuffer.dimensions)
|
print(myByteBuffer.dimensions)
|
||||||
print(myByteBuffer.to_list())
|
print(myByteBuffer.to_list())
|
||||||
|
|
||||||
sliceBuffer = myByteBuffer[0:16]
|
sliceBuffer = myByteBuffer[0:16]
|
||||||
print(sliceBuffer)
|
print(sliceBuffer)
|
||||||
|
|
||||||
@@ -1886,4 +1889,3 @@ class Buffer:
|
|||||||
the Buffer. If a template is not passed in all fields will be initialized to 0.
|
the Buffer. If a template is not passed in all fields will be initialized to 0.
|
||||||
:rtype: Buffer object
|
:rtype: Buffer object
|
||||||
:return: The newly created buffer as a PyObject.
|
:return: The newly created buffer as a PyObject.
|
||||||
|
|
||||||
|
@@ -416,6 +416,7 @@ def pymodule2sphinx(BASEPATH, module_name, module, title):
|
|||||||
del key, descr
|
del key, descr
|
||||||
|
|
||||||
classes = []
|
classes = []
|
||||||
|
submodules = []
|
||||||
|
|
||||||
for attribute in module_dir:
|
for attribute in module_dir:
|
||||||
if not attribute.startswith("_"):
|
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)
|
py_c_func2sphinx("", fw, module_name, None, attribute, value, is_class=False)
|
||||||
elif value_type == type:
|
elif value_type == type:
|
||||||
classes.append((attribute, value))
|
classes.append((attribute, value))
|
||||||
|
elif issubclass(value_type, types.ModuleType):
|
||||||
|
submodules.append((attribute, value))
|
||||||
elif value_type in (bool, int, float, str, tuple):
|
elif value_type in (bool, int, float, str, tuple):
|
||||||
# constant, not much fun we can do here except to list it.
|
# constant, not much fun we can do here except to list it.
|
||||||
# TODO, figure out some way to document these!
|
# 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)
|
write_indented_lines(" ", fw, "constant value %s" % repr(value), False)
|
||||||
fw("\n")
|
fw("\n")
|
||||||
else:
|
else:
|
||||||
print("\tnot documenting %s.%s" % (module_name, attribute))
|
print("\tnot documenting %s.%s of %r type" % (module_name, attribute, value_type.__name__))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
attribute_set.add(attribute)
|
attribute_set.add(attribute)
|
||||||
# TODO, more types...
|
# 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
|
# write collected classes now
|
||||||
for (type_name, value) in classes:
|
for (type_name, value) in classes:
|
||||||
# May need to be its own function
|
# May need to be its own function
|
||||||
|
@@ -44,7 +44,6 @@ set(SRC
|
|||||||
intern/GHOST_ISystem.cpp
|
intern/GHOST_ISystem.cpp
|
||||||
intern/GHOST_ISystemPaths.cpp
|
intern/GHOST_ISystemPaths.cpp
|
||||||
intern/GHOST_ModifierKeys.cpp
|
intern/GHOST_ModifierKeys.cpp
|
||||||
intern/GHOST_NDOFManager.cpp
|
|
||||||
intern/GHOST_Path-api.cpp
|
intern/GHOST_Path-api.cpp
|
||||||
intern/GHOST_Path-api.cpp
|
intern/GHOST_Path-api.cpp
|
||||||
intern/GHOST_Rect.cpp
|
intern/GHOST_Rect.cpp
|
||||||
@@ -74,12 +73,10 @@ set(SRC
|
|||||||
intern/GHOST_EventDragnDrop.h
|
intern/GHOST_EventDragnDrop.h
|
||||||
intern/GHOST_EventKey.h
|
intern/GHOST_EventKey.h
|
||||||
intern/GHOST_EventManager.h
|
intern/GHOST_EventManager.h
|
||||||
intern/GHOST_EventNDOF.h
|
|
||||||
intern/GHOST_EventString.h
|
intern/GHOST_EventString.h
|
||||||
intern/GHOST_EventTrackpad.h
|
intern/GHOST_EventTrackpad.h
|
||||||
intern/GHOST_EventWheel.h
|
intern/GHOST_EventWheel.h
|
||||||
intern/GHOST_ModifierKeys.h
|
intern/GHOST_ModifierKeys.h
|
||||||
intern/GHOST_NDOFManager.h
|
|
||||||
intern/GHOST_System.h
|
intern/GHOST_System.h
|
||||||
intern/GHOST_SystemPaths.h
|
intern/GHOST_SystemPaths.h
|
||||||
intern/GHOST_TimerManager.h
|
intern/GHOST_TimerManager.h
|
||||||
@@ -97,6 +94,20 @@ if(WITH_GHOST_DEBUG)
|
|||||||
add_definitions(-DWITH_GHOST_DEBUG)
|
add_definitions(-DWITH_GHOST_DEBUG)
|
||||||
endif()
|
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 OR WITH_GHOST_SDL)
|
||||||
if(WITH_HEADLESS)
|
if(WITH_HEADLESS)
|
||||||
@@ -138,6 +149,10 @@ if(WITH_HEADLESS OR WITH_GHOST_SDL)
|
|||||||
intern/GHOST_SystemPathsX11.cpp
|
intern/GHOST_SystemPathsX11.cpp
|
||||||
intern/GHOST_SystemPathsX11.h
|
intern/GHOST_SystemPathsX11.h
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if(NOT WITH_INSTALL_PORTABLE)
|
||||||
|
add_definitions(-DPREFIX="${CMAKE_INSTALL_PREFIX}")
|
||||||
|
endif()
|
||||||
elseif(WIN32)
|
elseif(WIN32)
|
||||||
|
|
||||||
list(APPEND SRC
|
list(APPEND SRC
|
||||||
@@ -164,6 +179,15 @@ elseif(APPLE)
|
|||||||
intern/GHOST_SystemPathsCocoa.h
|
intern/GHOST_SystemPathsCocoa.h
|
||||||
intern/GHOST_WindowCocoa.h
|
intern/GHOST_WindowCocoa.h
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if(WITH_INPUT_NDOF)
|
||||||
|
list(APPEND SRC
|
||||||
|
intern/GHOST_NDOFManagerCocoa.mm
|
||||||
|
|
||||||
|
intern/GHOST_NDOFManagerCocoa.h
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
else()
|
else()
|
||||||
list(APPEND SRC
|
list(APPEND SRC
|
||||||
intern/GHOST_DisplayManagerCarbon.cpp
|
intern/GHOST_DisplayManagerCarbon.cpp
|
||||||
@@ -184,10 +208,6 @@ elseif(APPLE)
|
|||||||
|
|
||||||
elseif(UNIX)
|
elseif(UNIX)
|
||||||
|
|
||||||
if(WITH_X11_XINPUT)
|
|
||||||
add_definitions(-DWITH_X11_XINPUT)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
list(APPEND INC_SYS
|
list(APPEND INC_SYS
|
||||||
${X11_X11_INCLUDE_PATH}
|
${X11_X11_INCLUDE_PATH}
|
||||||
)
|
)
|
||||||
@@ -204,10 +224,6 @@ elseif(UNIX)
|
|||||||
intern/GHOST_WindowX11.h
|
intern/GHOST_WindowX11.h
|
||||||
)
|
)
|
||||||
|
|
||||||
if(NOT WITH_INSTALL_PORTABLE)
|
|
||||||
add_definitions(-DPREFIX="${CMAKE_INSTALL_PREFIX}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(X11_XF86keysym_INCLUDE_PATH)
|
if(X11_XF86keysym_INCLUDE_PATH)
|
||||||
add_definitions(-DWITH_XF86KEYSYM)
|
add_definitions(-DWITH_XF86KEYSYM)
|
||||||
list(APPEND INC_SYS
|
list(APPEND INC_SYS
|
||||||
@@ -215,6 +231,22 @@ elseif(UNIX)
|
|||||||
)
|
)
|
||||||
endif()
|
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)
|
elseif(WIN32)
|
||||||
if(MSVC)
|
if(MSVC)
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /WX")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /WX")
|
||||||
@@ -238,6 +270,15 @@ elseif(WIN32)
|
|||||||
intern/GHOST_WindowWin32.h
|
intern/GHOST_WindowWin32.h
|
||||||
intern/GHOST_TaskbarWin32.h
|
intern/GHOST_TaskbarWin32.h
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if(WITH_INPUT_NDOF)
|
||||||
|
list(APPEND SRC
|
||||||
|
intern/GHOST_NDOFManagerWin32.cpp
|
||||||
|
|
||||||
|
intern/GHOST_NDOFManagerWin32.h
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
blender_add_lib(bf_intern_ghost "${SRC}" "${INC}" "${INC_SYS}")
|
blender_add_lib(bf_intern_ghost "${SRC}" "${INC}" "${INC_SYS}")
|
||||||
|
@@ -289,21 +289,6 @@ extern GHOST_TSuccess GHOST_SetProgressBar(GHOST_WindowHandle windowhandle, floa
|
|||||||
*/
|
*/
|
||||||
extern GHOST_TSuccess GHOST_EndProgressBar(GHOST_WindowHandle windowhandle);
|
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
|
** Cursor management functionality
|
||||||
***************************************************************************************/
|
***************************************************************************************/
|
||||||
|
@@ -298,22 +298,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual GHOST_TSuccess removeEventConsumer(GHOST_IEventConsumer* consumer) = 0;
|
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
|
** Cursor management functionality
|
||||||
***************************************************************************************/
|
***************************************************************************************/
|
||||||
|
@@ -47,11 +47,6 @@ typedef unsigned short GHOST_TUns16;
|
|||||||
typedef int GHOST_TInt32;
|
typedef int GHOST_TInt32;
|
||||||
typedef unsigned int GHOST_TUns32;
|
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)
|
#if defined(WIN32) && !defined(FREE_WINDOWS)
|
||||||
typedef __int64 GHOST_TInt64;
|
typedef __int64 GHOST_TInt64;
|
||||||
typedef unsigned __int64 GHOST_TUns64;
|
typedef unsigned __int64 GHOST_TUns64;
|
||||||
@@ -440,37 +435,33 @@ typedef struct {
|
|||||||
GHOST_TUns8 **strings;
|
GHOST_TUns8 **strings;
|
||||||
} GHOST_TStringArray;
|
} GHOST_TStringArray;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
/* original patch used floats, but the driver return ints and uns. We will calibrate in view, no sense on doing conversions twice */
|
GHOST_kNotStarted,
|
||||||
/* as all USB device controls are likely to use ints, this is also more future proof */
|
GHOST_kStarting,
|
||||||
//typedef struct {
|
GHOST_kInProgress,
|
||||||
// /** N-degree of freedom device data */
|
GHOST_kFinishing,
|
||||||
// float tx, ty, tz; /** -x left, +y up, +z forward */
|
GHOST_kFinished
|
||||||
// float rx, ry, rz;
|
} GHOST_TProgress;
|
||||||
// float dt;
|
|
||||||
//} GHOST_TEventNDOFData;
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/** N-degree of freedom device data v2*/
|
/** N-degree of freedom device data v3 [GSoC 2010] */
|
||||||
int changed;
|
// Each component normally ranges from -1 to +1, but can exceed that.
|
||||||
GHOST_TUns64 client;
|
// These use blender standard view coordinates, with positive rotations being CCW about the axis.
|
||||||
GHOST_TUns64 address;
|
float tx, ty, tz; // translation
|
||||||
GHOST_TInt16 tx, ty, tz; /** -x left, +y up, +z forward */
|
float rx, ry, rz; // rotation:
|
||||||
GHOST_TInt16 rx, ry, rz;
|
// axis = (rx,ry,rz).normalized
|
||||||
GHOST_TInt16 buttons;
|
// amount = (rx,ry,rz).magnitude [in revolutions, 1.0 = 360 deg]
|
||||||
GHOST_TUns64 time;
|
float dt; // time since previous NDOF Motion event
|
||||||
GHOST_TUns64 delta;
|
GHOST_TProgress progress; // Starting, InProgress or Finishing (for modal handlers)
|
||||||
} GHOST_TEventNDOFData;
|
} GHOST_TEventNDOFMotionData;
|
||||||
|
|
||||||
typedef int (*GHOST_NDOFLibraryInit_fp)(void);
|
typedef enum { GHOST_kPress, GHOST_kRelease } GHOST_TButtonAction;
|
||||||
typedef void (*GHOST_NDOFLibraryShutdown_fp)(void* deviceHandle);
|
// good for mouse or other buttons too, hmmm?
|
||||||
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.
|
typedef struct {
|
||||||
// not necessary faster, but better integration with other events.
|
GHOST_TButtonAction action;
|
||||||
|
short button;
|
||||||
//typedef int (*GHOST_NDOFEventHandler_fp)(float* result7, void* deviceHandle, unsigned int message, unsigned int* wParam, unsigned long* lParam);
|
} GHOST_TEventNDOFButtonData;
|
||||||
//typedef void (*GHOST_NDOFCallBack_fp)(GHOST_TEventNDOFDataV2 *VolDatas);
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/** The key code. */
|
/** The key code. */
|
||||||
|
@@ -11,7 +11,7 @@ if window_system == 'darwin':
|
|||||||
sources += env.Glob('intern/*.mm')
|
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']
|
defs=['_USE_MATH_DEFINES']
|
||||||
|
|
||||||
incs = '. ../string #extern/glew/include #source/blender/imbuf #source/blender/makesdna ' + env['BF_OPENGL_INC']
|
incs = '. ../string #extern/glew/include #source/blender/imbuf #source/blender/makesdna ' + env['BF_OPENGL_INC']
|
||||||
@@ -78,6 +78,24 @@ if env['BF_GHOST_DEBUG']:
|
|||||||
else:
|
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'):
|
if window_system in ('win32-vc', 'win32-mingw', 'cygwin', 'linuxcross', 'win64-vc'):
|
||||||
incs = env['BF_WINTAB_INC'] + ' ' + incs
|
incs = env['BF_WINTAB_INC'] + ' ' + incs
|
||||||
|
|
||||||
|
@@ -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_TStandardCursor GHOST_GetCursorShape(GHOST_WindowHandle windowhandle)
|
||||||
{
|
{
|
||||||
GHOST_IWindow* window = (GHOST_IWindow*) windowhandle;
|
GHOST_IWindow* window = (GHOST_IWindow*) windowhandle;
|
||||||
|
@@ -35,8 +35,11 @@
|
|||||||
#include "GHOST_DisplayManagerWin32.h"
|
#include "GHOST_DisplayManagerWin32.h"
|
||||||
#include "GHOST_Debug.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>
|
#include <windows.h>
|
||||||
|
|
||||||
|
// We do not support multiple monitors at the moment
|
||||||
#define COMPILE_MULTIMON_STUBS
|
#define COMPILE_MULTIMON_STUBS
|
||||||
#ifndef FREE_WINDOWS
|
#ifndef FREE_WINDOWS
|
||||||
#include <multimon.h>
|
#include <multimon.h>
|
||||||
|
@@ -33,6 +33,7 @@
|
|||||||
|
|
||||||
#include "GHOST_Debug.h"
|
#include "GHOST_Debug.h"
|
||||||
#include "GHOST_DropTargetWin32.h"
|
#include "GHOST_DropTargetWin32.h"
|
||||||
|
#include <ShellApi.h>
|
||||||
|
|
||||||
#ifdef GHOST_DEBUG
|
#ifdef GHOST_DEBUG
|
||||||
// utility
|
// utility
|
||||||
|
@@ -33,7 +33,6 @@
|
|||||||
#ifndef _GHOST_DROP_TARGET_WIN32_H_
|
#ifndef _GHOST_DROP_TARGET_WIN32_H_
|
||||||
#define _GHOST_DROP_TARGET_WIN32_H_
|
#define _GHOST_DROP_TARGET_WIN32_H_
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <GHOST_Types.h>
|
#include <GHOST_Types.h>
|
||||||
#include "GHOST_WindowWin32.h"
|
#include "GHOST_WindowWin32.h"
|
||||||
|
@@ -42,7 +42,7 @@
|
|||||||
#include "GHOST_EventManager.h"
|
#include "GHOST_EventManager.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include "GHOST_Debug.h"
|
#include "GHOST_Debug.h"
|
||||||
|
#include <stdio.h> // [mce] temp debug
|
||||||
|
|
||||||
GHOST_EventManager::GHOST_EventManager()
|
GHOST_EventManager::GHOST_EventManager()
|
||||||
{
|
{
|
||||||
|
@@ -20,43 +20,39 @@
|
|||||||
* ***** END GPL LICENSE BLOCK *****
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** \file ghost/intern/GHOST_EventNDOF.h
|
|
||||||
* \ingroup GHOST
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef _GHOST_EVENT_NDOF_H_
|
#ifndef _GHOST_EVENT_NDOF_H_
|
||||||
#define _GHOST_EVENT_NDOF_H_
|
#define _GHOST_EVENT_NDOF_H_
|
||||||
|
|
||||||
#include "GHOST_Event.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:
|
class GHOST_EventNDOFMotion : public GHOST_Event
|
||||||
/** translation & rotation from the device. */
|
{
|
||||||
GHOST_TEventNDOFData m_ndofEventData;
|
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_
|
#endif // _GHOST_EVENT_NDOF_H_
|
||||||
|
|
||||||
|
@@ -1,4 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
@@ -15,122 +17,458 @@
|
|||||||
* along with this program; if not, write to the Free Software Foundation,
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
* Contributor(s): none yet.
|
* Contributor(s):
|
||||||
|
* Mike Erwin
|
||||||
*
|
*
|
||||||
* ***** END GPL LICENSE BLOCK *****
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** \file ghost/intern/GHOST_NDOFManager.cpp
|
#include "GHOST_Debug.h"
|
||||||
* \ingroup GHOST
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include <stdio.h> /* just for printf */
|
|
||||||
|
|
||||||
#include "GHOST_NDOFManager.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
|
||||||
// the variable is outside the class because it must be accessed from plugin
|
// printable version of each GHOST_TProgress value
|
||||||
static volatile GHOST_TEventNDOFData currentNdofValues = {0,0,0,0,0,0,0,0,0,0,0};
|
static const char* progress_string[] =
|
||||||
|
{"not started","starting","in progress","finishing","finished"};
|
||||||
#if !defined(_WIN32) && !defined(__APPLE__)
|
|
||||||
#include "GHOST_SystemX11.h"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace
|
#ifdef DEBUG_NDOF_BUTTONS
|
||||||
{
|
static const char* ndof_button_names[] = {
|
||||||
GHOST_NDOFLibraryInit_fp ndofLibraryInit = 0;
|
// used internally, never sent
|
||||||
GHOST_NDOFLibraryShutdown_fp ndofLibraryShutdown = 0;
|
"NDOF_BUTTON_NONE",
|
||||||
GHOST_NDOFDeviceOpen_fp ndofDeviceOpen = 0;
|
// these two are available from any 3Dconnexion device
|
||||||
}
|
"NDOF_BUTTON_MENU",
|
||||||
|
"NDOF_BUTTON_FIT",
|
||||||
GHOST_NDOFManager::GHOST_NDOFManager()
|
// standard views
|
||||||
{
|
"NDOF_BUTTON_TOP",
|
||||||
m_DeviceHandle = 0;
|
"NDOF_BUTTON_BOTTOM",
|
||||||
|
"NDOF_BUTTON_LEFT",
|
||||||
// discover the API from the plugin
|
"NDOF_BUTTON_RIGHT",
|
||||||
ndofLibraryInit = 0;
|
"NDOF_BUTTON_FRONT",
|
||||||
ndofLibraryShutdown = 0;
|
"NDOF_BUTTON_BACK",
|
||||||
ndofDeviceOpen = 0;
|
// more views
|
||||||
}
|
"NDOF_BUTTON_ISO1",
|
||||||
|
"NDOF_BUTTON_ISO2",
|
||||||
GHOST_NDOFManager::~GHOST_NDOFManager()
|
// 90 degree rotations
|
||||||
{
|
"NDOF_BUTTON_ROLL_CW",
|
||||||
if (ndofLibraryShutdown)
|
"NDOF_BUTTON_ROLL_CCW",
|
||||||
ndofLibraryShutdown(m_DeviceHandle);
|
"NDOF_BUTTON_SPIN_CW",
|
||||||
|
"NDOF_BUTTON_SPIN_CCW",
|
||||||
m_DeviceHandle = 0;
|
"NDOF_BUTTON_TILT_CW",
|
||||||
}
|
"NDOF_BUTTON_TILT_CCW",
|
||||||
|
// device control
|
||||||
|
"NDOF_BUTTON_ROTATE",
|
||||||
int
|
"NDOF_BUTTON_PANZOOM",
|
||||||
GHOST_NDOFManager::deviceOpen(GHOST_IWindow* window,
|
"NDOF_BUTTON_DOMINANT",
|
||||||
GHOST_NDOFLibraryInit_fp setNdofLibraryInit,
|
"NDOF_BUTTON_PLUS",
|
||||||
GHOST_NDOFLibraryShutdown_fp setNdofLibraryShutdown,
|
"NDOF_BUTTON_MINUS",
|
||||||
GHOST_NDOFDeviceOpen_fp setNdofDeviceOpen)
|
// general-purpose buttons
|
||||||
{
|
"NDOF_BUTTON_1",
|
||||||
int Pid;
|
"NDOF_BUTTON_2",
|
||||||
|
"NDOF_BUTTON_3",
|
||||||
ndofLibraryInit = setNdofLibraryInit;
|
"NDOF_BUTTON_4",
|
||||||
ndofLibraryShutdown = setNdofLibraryShutdown;
|
"NDOF_BUTTON_5",
|
||||||
ndofDeviceOpen = setNdofDeviceOpen;
|
"NDOF_BUTTON_6",
|
||||||
|
"NDOF_BUTTON_7",
|
||||||
if (ndofLibraryInit && ndofDeviceOpen)
|
"NDOF_BUTTON_8",
|
||||||
{
|
"NDOF_BUTTON_9",
|
||||||
Pid= ndofLibraryInit();
|
"NDOF_BUTTON_10",
|
||||||
#if 0
|
};
|
||||||
printf("%i client \n", Pid);
|
|
||||||
#endif
|
#endif
|
||||||
#if defined(WITH_HEADLESS)
|
|
||||||
/* do nothing */
|
|
||||||
#elif defined(_WIN32) || defined(__APPLE__)
|
|
||||||
m_DeviceHandle = ndofDeviceOpen((void *)¤tNdofValues);
|
|
||||||
#elif defined(WITH_GHOST_SDL)
|
|
||||||
/* do nothing */
|
|
||||||
#else
|
|
||||||
GHOST_SystemX11 *sys;
|
|
||||||
sys = static_cast<GHOST_SystemX11*>(GHOST_ISystem::getSystem());
|
|
||||||
void *ndofInfo = sys->prepareNdofInfo(¤tNdofValues);
|
|
||||||
m_DeviceHandle = ndofDeviceOpen(ndofInfo);
|
|
||||||
#endif
|
|
||||||
return (Pid > 0) ? 0 : 1;
|
|
||||||
|
|
||||||
} else
|
static const NDOF_ButtonT SpaceNavigator_HID_map[] = {
|
||||||
return 1;
|
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
|
||||||
|
};
|
||||||
|
|
||||||
|
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
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 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?
|
||||||
|
};
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
// 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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool GHOST_NDOFManager::setDevice(unsigned short vendor_id, unsigned short product_id)
|
||||||
bool
|
|
||||||
GHOST_NDOFManager::available() const
|
|
||||||
{
|
{
|
||||||
return 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;
|
||||||
|
|
||||||
|
// -- 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
|
||||||
|
|
||||||
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;
|
return true;
|
||||||
}else
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GHOST_NDOFManager::updateTranslation(short t[3], GHOST_TUns64 time)
|
||||||
|
{
|
||||||
|
memcpy(m_translation, t, sizeof(m_translation));
|
||||||
|
m_motionTime = time;
|
||||||
|
m_motionEventPending = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
m_system.pushEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GHOST_NDOFManager::updateButton(int button_number, bool press, GHOST_TUns64 time)
|
||||||
|
{
|
||||||
|
GHOST_IWindow* window = m_system.getWindowManager()->getActiveWindow();
|
||||||
|
|
||||||
|
#ifdef DEBUG_NDOF_BUTTONS
|
||||||
|
if (m_deviceType != NDOF_UnknownDevice)
|
||||||
|
printf("ndof: button %d -> ", button_number);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool atHomePosition(GHOST_TEventNDOFMotionData* ndof)
|
||||||
|
{
|
||||||
|
#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;
|
return false;
|
||||||
|
|
||||||
}
|
m_motionEventPending = false; // any pending motion is handled right now
|
||||||
|
|
||||||
void GHOST_NDOFManager::GHOST_NDOFGetDatas(GHOST_TEventNDOFData &datas) const
|
GHOST_IWindow* window = m_system.getWindowManager()->getActiveWindow();
|
||||||
{
|
|
||||||
datas.tx = currentNdofValues.tx;
|
if (window == NULL) {
|
||||||
datas.ty = currentNdofValues.ty;
|
return false; // delivery will fail, so don't bother sending
|
||||||
datas.tz = currentNdofValues.tz;
|
}
|
||||||
datas.rx = currentNdofValues.rx;
|
|
||||||
datas.ry = currentNdofValues.ry;
|
GHOST_EventNDOFMotion* event = new GHOST_EventNDOFMotion(m_motionTime, window);
|
||||||
datas.rz = currentNdofValues.rz;
|
GHOST_TEventNDOFMotionData* data = (GHOST_TEventNDOFMotionData*) event->getData();
|
||||||
datas.buttons = currentNdofValues.buttons;
|
|
||||||
datas.client = currentNdofValues.client;
|
// scale axis values here to normalize them to around +/- 1
|
||||||
datas.address = currentNdofValues.address;
|
// they are scaled again for overall sensitivity in the WM based on user prefs
|
||||||
datas.time = currentNdofValues.time;
|
|
||||||
datas.delta = currentNdofValues.delta;
|
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;
|
||||||
}
|
}
|
||||||
|
@@ -1,4 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
@@ -15,43 +17,142 @@
|
|||||||
* along with this program; if not, write to the Free Software Foundation,
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
* Contributor(s): none yet.
|
* Contributor(s):
|
||||||
|
* Mike Erwin
|
||||||
*
|
*
|
||||||
* ***** END GPL LICENSE BLOCK *****
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** \file ghost/intern/GHOST_NDOFManager.h
|
|
||||||
* \ingroup GHOST
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef _GHOST_NDOFMANAGER_H_
|
#ifndef _GHOST_NDOFMANAGER_H_
|
||||||
#define _GHOST_NDOFMANAGER_H_
|
#define _GHOST_NDOFMANAGER_H_
|
||||||
|
|
||||||
#include "GHOST_System.h"
|
#include "GHOST_System.h"
|
||||||
#include "GHOST_IWindow.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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
|
class GHOST_NDOFManager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GHOST_NDOFManager();
|
GHOST_NDOFManager(GHOST_System&);
|
||||||
virtual ~GHOST_NDOFManager();
|
|
||||||
|
|
||||||
int deviceOpen(GHOST_IWindow* window,
|
virtual ~GHOST_NDOFManager() {};
|
||||||
GHOST_NDOFLibraryInit_fp setNdofLibraryInit,
|
|
||||||
GHOST_NDOFLibraryShutdown_fp setNdofLibraryShutdown,
|
|
||||||
GHOST_NDOFDeviceOpen_fp setNdofDeviceOpen);
|
|
||||||
|
|
||||||
void GHOST_NDOFGetDatas(GHOST_TEventNDOFData &datas) const;
|
// 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;
|
||||||
|
|
||||||
bool available() const;
|
// each platform's device detection should call this
|
||||||
bool event_present() const;
|
// 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:
|
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
|
#endif
|
||||||
|
53
intern/ghost/intern/GHOST_NDOFManagerCocoa.h
Normal file
53
intern/ghost/intern/GHOST_NDOFManagerCocoa.h
Normal file
@@ -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
|
176
intern/ghost/intern/GHOST_NDOFManagerCocoa.mm
Normal file
176
intern/ghost/intern/GHOST_NDOFManagerCocoa.mm
Normal file
@@ -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
|
45
intern/ghost/intern/GHOST_NDOFManagerWin32.cpp
Normal file
45
intern/ghost/intern/GHOST_NDOFManagerWin32.cpp
Normal file
@@ -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
|
44
intern/ghost/intern/GHOST_NDOFManagerWin32.h
Normal file
44
intern/ghost/intern/GHOST_NDOFManagerWin32.h
Normal file
@@ -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
|
105
intern/ghost/intern/GHOST_NDOFManagerX11.cpp
Normal file
105
intern/ghost/intern/GHOST_NDOFManagerX11.cpp
Normal file
@@ -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 */
|
50
intern/ghost/intern/GHOST_NDOFManagerX11.h
Normal file
50
intern/ghost/intern/GHOST_NDOFManagerX11.h
Normal file
@@ -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 */
|
||||||
|
|
@@ -46,7 +46,13 @@
|
|||||||
|
|
||||||
|
|
||||||
GHOST_System::GHOST_System()
|
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 GHOST_System::dispatchEvents()
|
||||||
{
|
{
|
||||||
bool handled;
|
bool handled = false;
|
||||||
if (m_eventManager) {
|
|
||||||
handled = m_eventManager->dispatchEvents();
|
#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 {
|
#endif
|
||||||
handled = false;
|
|
||||||
|
if (m_eventManager) {
|
||||||
|
handled |= m_eventManager->dispatchEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_timerManager->fireTimers(getMilliSeconds());
|
m_timerManager->fireTimers(getMilliSeconds());
|
||||||
@@ -243,18 +254,6 @@ GHOST_TSuccess GHOST_System::pushEvent(GHOST_IEvent* event)
|
|||||||
return success;
|
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_TSuccess GHOST_System::getModifierKeyState(GHOST_TModifierKeyMask mask, bool& isDown) const
|
||||||
{
|
{
|
||||||
GHOST_ModifierKeys keys;
|
GHOST_ModifierKeys keys;
|
||||||
@@ -285,12 +284,6 @@ GHOST_TSuccess GHOST_System::init()
|
|||||||
m_timerManager = new GHOST_TimerManager ();
|
m_timerManager = new GHOST_TimerManager ();
|
||||||
m_windowManager = new GHOST_WindowManager ();
|
m_windowManager = new GHOST_WindowManager ();
|
||||||
m_eventManager = new GHOST_EventManager ();
|
m_eventManager = new GHOST_EventManager ();
|
||||||
m_ndofManager = new GHOST_NDOFManager();
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
if(m_ndofManager)
|
|
||||||
printf("ndof manager \n");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef GHOST_DEBUG
|
#ifdef GHOST_DEBUG
|
||||||
if (m_eventManager) {
|
if (m_eventManager) {
|
||||||
@@ -328,10 +321,12 @@ GHOST_TSuccess GHOST_System::exit()
|
|||||||
delete m_eventManager;
|
delete m_eventManager;
|
||||||
m_eventManager = 0;
|
m_eventManager = 0;
|
||||||
}
|
}
|
||||||
|
#ifdef WITH_INPUT_NDOF
|
||||||
if (m_ndofManager) {
|
if (m_ndofManager) {
|
||||||
delete m_ndofManager;
|
delete m_ndofManager;
|
||||||
m_ndofManager = 0;
|
m_ndofManager = 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return GHOST_kSuccess;
|
return GHOST_kSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -190,25 +190,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual GHOST_TSuccess removeEventConsumer(GHOST_IEventConsumer* consumer);
|
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
|
** Cursor management functionality
|
||||||
***************************************************************************************/
|
***************************************************************************************/
|
||||||
@@ -268,11 +249,13 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual inline GHOST_WindowManager* getWindowManager() const;
|
virtual inline GHOST_WindowManager* getWindowManager() const;
|
||||||
|
|
||||||
|
#ifdef WITH_INPUT_NDOF
|
||||||
/**
|
/**
|
||||||
* Returns a pointer to our n-degree of freedeom manager.
|
* Returns a pointer to our n-degree of freedeom manager.
|
||||||
* @return 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;
|
virtual inline GHOST_NDOFManager* getNDOFManager() const;
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the state of all modifier keys.
|
* Returns the state of all modifier keys.
|
||||||
@@ -337,8 +320,10 @@ protected:
|
|||||||
/** The event manager. */
|
/** The event manager. */
|
||||||
GHOST_EventManager* m_eventManager;
|
GHOST_EventManager* m_eventManager;
|
||||||
|
|
||||||
|
#ifdef WITH_INPUT_NDOF
|
||||||
/** The N-degree of freedom device manager */
|
/** The N-degree of freedom device manager */
|
||||||
GHOST_NDOFManager* m_ndofManager;
|
GHOST_NDOFManager* m_ndofManager;
|
||||||
|
#endif
|
||||||
|
|
||||||
/** Prints all the events. */
|
/** Prints all the events. */
|
||||||
#ifdef GHOST_DEBUG
|
#ifdef GHOST_DEBUG
|
||||||
@@ -364,10 +349,12 @@ inline GHOST_WindowManager* GHOST_System::getWindowManager() const
|
|||||||
return m_windowManager;
|
return m_windowManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WITH_INPUT_NDOF
|
||||||
inline GHOST_NDOFManager* GHOST_System::getNDOFManager() const
|
inline GHOST_NDOFManager* GHOST_System::getNDOFManager() const
|
||||||
{
|
{
|
||||||
return m_ndofManager;
|
return m_ndofManager;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // _GHOST_SYSTEM_H_
|
#endif // _GHOST_SYSTEM_H_
|
||||||
|
|
||||||
|
@@ -220,6 +220,11 @@ public:
|
|||||||
*/
|
*/
|
||||||
GHOST_TSuccess handleApplicationBecomeActiveEvent();
|
GHOST_TSuccess handleApplicationBecomeActiveEvent();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* External objects should call this when they send an event outside processEvents.
|
||||||
|
*/
|
||||||
|
void notifyExternalEventProcessed();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see GHOST_ISystem
|
* @see GHOST_ISystem
|
||||||
*/
|
*/
|
||||||
@@ -267,7 +272,7 @@ protected:
|
|||||||
/** Start time at initialization. */
|
/** Start time at initialization. */
|
||||||
GHOST_TUns64 m_start_time;
|
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;
|
bool m_outsideLoopEventProcessed;
|
||||||
|
|
||||||
/** Raised window is not yet known by the window manager, so delay application become active event handling */
|
/** Raised window is not yet known by the window manager, so delay application become active event handling */
|
||||||
|
@@ -21,7 +21,7 @@
|
|||||||
*
|
*
|
||||||
* The Original Code is: all of this file.
|
* The Original Code is: all of this file.
|
||||||
*
|
*
|
||||||
* Contributor(s): Maarten Gribnau 05/2001
|
* Contributors: Maarten Gribnau 05/2001
|
||||||
* Damien Plisson 09/2009
|
* Damien Plisson 09/2009
|
||||||
*
|
*
|
||||||
* ***** END GPL LICENSE BLOCK *****
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
@@ -43,16 +43,17 @@
|
|||||||
#include "GHOST_EventButton.h"
|
#include "GHOST_EventButton.h"
|
||||||
#include "GHOST_EventCursor.h"
|
#include "GHOST_EventCursor.h"
|
||||||
#include "GHOST_EventWheel.h"
|
#include "GHOST_EventWheel.h"
|
||||||
#include "GHOST_EventNDOF.h"
|
|
||||||
#include "GHOST_EventTrackpad.h"
|
#include "GHOST_EventTrackpad.h"
|
||||||
#include "GHOST_EventDragnDrop.h"
|
#include "GHOST_EventDragnDrop.h"
|
||||||
#include "GHOST_EventString.h"
|
#include "GHOST_EventString.h"
|
||||||
|
|
||||||
#include "GHOST_TimerManager.h"
|
#include "GHOST_TimerManager.h"
|
||||||
#include "GHOST_TimerTask.h"
|
#include "GHOST_TimerTask.h"
|
||||||
#include "GHOST_WindowManager.h"
|
#include "GHOST_WindowManager.h"
|
||||||
#include "GHOST_WindowCocoa.h"
|
#include "GHOST_WindowCocoa.h"
|
||||||
#include "GHOST_NDOFManager.h"
|
#ifdef WITH_INPUT_NDOF
|
||||||
|
#include "GHOST_NDOFManagerCocoa.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "AssertMacros.h"
|
#include "AssertMacros.h"
|
||||||
|
|
||||||
#pragma mark KeyMap, mouse converters
|
#pragma mark KeyMap, mouse converters
|
||||||
@@ -596,6 +597,11 @@ GHOST_TSuccess GHOST_SystemCocoa::init()
|
|||||||
|
|
||||||
GHOST_TSuccess success = GHOST_System::init();
|
GHOST_TSuccess success = GHOST_System::init();
|
||||||
if (success) {
|
if (success) {
|
||||||
|
|
||||||
|
#ifdef WITH_INPUT_NDOF
|
||||||
|
m_ndofManager = new GHOST_NDOFManagerCocoa(*this);
|
||||||
|
#endif
|
||||||
|
|
||||||
//ProcessSerialNumber psn;
|
//ProcessSerialNumber psn;
|
||||||
|
|
||||||
//Carbon stuff to move window & menu to foreground
|
//Carbon stuff to move window & menu to foreground
|
||||||
@@ -1007,6 +1013,11 @@ GHOST_TSuccess GHOST_SystemCocoa::handleApplicationBecomeActiveEvent()
|
|||||||
return GHOST_kSuccess;
|
return GHOST_kSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GHOST_SystemCocoa::notifyExternalEventProcessed()
|
||||||
|
{
|
||||||
|
m_outsideLoopEventProcessed = true;
|
||||||
|
}
|
||||||
|
|
||||||
//Note: called from NSWindow delegate
|
//Note: called from NSWindow delegate
|
||||||
GHOST_TSuccess GHOST_SystemCocoa::handleWindowEvent(GHOST_TEventType eventType, GHOST_WindowCocoa* window)
|
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;
|
GHOST_TInt32 delta;
|
||||||
|
|
||||||
double deltaF = [event deltaY];
|
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
|
if (deltaF == 0.0) break; //discard trackpad delta=0 events
|
||||||
|
|
||||||
delta = deltaF > 0.0 ? 1 : -1;
|
delta = deltaF > 0.0 ? 1 : -1;
|
||||||
|
@@ -32,12 +32,9 @@
|
|||||||
|
|
||||||
#include "GHOST_SystemPathsWin32.h"
|
#include "GHOST_SystemPathsWin32.h"
|
||||||
|
|
||||||
#define WIN32_LEAN_AND_MEAN
|
#ifndef _WIN32_IE
|
||||||
#ifdef _WIN32_IE
|
|
||||||
#undef _WIN32_IE
|
|
||||||
#endif
|
|
||||||
#define _WIN32_IE 0x0501
|
#define _WIN32_IE 0x0501
|
||||||
#include <windows.h>
|
#endif
|
||||||
#include <shlobj.h>
|
#include <shlobj.h>
|
||||||
|
|
||||||
#if defined(__MINGW32__) || defined(__CYGWIN__)
|
#if defined(__MINGW32__) || defined(__CYGWIN__)
|
||||||
|
@@ -38,6 +38,8 @@
|
|||||||
#error WIN32 only!
|
#error WIN32 only!
|
||||||
#endif // WIN32
|
#endif // WIN32
|
||||||
|
|
||||||
|
#define _WIN32_WINNT 0x501 // require Windows XP or newer
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
#include "GHOST_SystemPaths.h"
|
#include "GHOST_SystemPaths.h"
|
||||||
|
@@ -43,7 +43,11 @@
|
|||||||
#include <stdio.h> // for fprintf only
|
#include <stdio.h> // for fprintf only
|
||||||
#include <cstdlib> // for exit
|
#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()
|
GHOST_SystemPathsX11::GHOST_SystemPathsX11()
|
||||||
{
|
{
|
||||||
@@ -56,21 +60,12 @@ GHOST_SystemPathsX11::~GHOST_SystemPathsX11()
|
|||||||
const GHOST_TUns8* GHOST_SystemPathsX11::getSystemDir() const
|
const GHOST_TUns8* GHOST_SystemPathsX11::getSystemDir() const
|
||||||
{
|
{
|
||||||
/* no prefix assumes a portable build which only uses bundled scripts */
|
/* no prefix assumes a portable build which only uses bundled scripts */
|
||||||
#ifdef PREFIX
|
return (const GHOST_TUns8 *)static_path;
|
||||||
return (GHOST_TUns8*) PREFIX "/share";
|
|
||||||
#else
|
|
||||||
return NULL;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const GHOST_TUns8* GHOST_SystemPathsX11::getUserDir() const
|
const GHOST_TUns8* GHOST_SystemPathsX11::getUserDir() const
|
||||||
{
|
{
|
||||||
const char* env = getenv("HOME");
|
return (const GHOST_TUns8 *)getenv("HOME");
|
||||||
if(env) {
|
|
||||||
return (GHOST_TUns8*) env;
|
|
||||||
} else {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const GHOST_TUns8* GHOST_SystemPathsX11::getBinaryDir() const
|
const GHOST_TUns8* GHOST_SystemPathsX11::getBinaryDir() const
|
||||||
|
@@ -146,7 +146,7 @@ convertSDLKey(SDL_Scancode key)
|
|||||||
if ((key >= SDL_SCANCODE_A) && (key <= SDL_SCANCODE_Z)) {
|
if ((key >= SDL_SCANCODE_A) && (key <= SDL_SCANCODE_Z)) {
|
||||||
type= GHOST_TKey( key - SDL_SCANCODE_A + int(GHOST_kKeyA));
|
type= GHOST_TKey( key - SDL_SCANCODE_A + int(GHOST_kKeyA));
|
||||||
} else if ((key >= SDL_SCANCODE_1) && (key <= SDL_SCANCODE_0)) {
|
} else if ((key >= SDL_SCANCODE_1) && (key <= SDL_SCANCODE_0)) {
|
||||||
type= GHOST_TKey(key - SDL_SCANCODE_1 + int(GHOST_kKey0));
|
type= (key == SDL_SCANCODE_0) ? GHOST_kKey0 : GHOST_TKey(key - SDL_SCANCODE_1 + int(GHOST_kKey1));
|
||||||
} else if ((key >= SDL_SCANCODE_F1) && (key <= SDL_SCANCODE_F12)) {
|
} else if ((key >= SDL_SCANCODE_F1) && (key <= SDL_SCANCODE_F12)) {
|
||||||
type= GHOST_TKey(key - SDL_SCANCODE_F1 + int(GHOST_kKeyF1));
|
type= GHOST_TKey(key - SDL_SCANCODE_F1 + int(GHOST_kKeyF1));
|
||||||
} else if ((key >= SDL_SCANCODE_F13) && (key <= SDL_SCANCODE_F24)) {
|
} else if ((key >= SDL_SCANCODE_F13) && (key <= SDL_SCANCODE_F24)) {
|
||||||
@@ -167,6 +167,8 @@ convertSDLKey(SDL_Scancode key)
|
|||||||
GXMAP(type,SDL_SCANCODE_APOSTROPHE, GHOST_kKeyQuote);
|
GXMAP(type,SDL_SCANCODE_APOSTROPHE, GHOST_kKeyQuote);
|
||||||
GXMAP(type,SDL_SCANCODE_GRAVE, GHOST_kKeyAccentGrave);
|
GXMAP(type,SDL_SCANCODE_GRAVE, GHOST_kKeyAccentGrave);
|
||||||
GXMAP(type,SDL_SCANCODE_MINUS, GHOST_kKeyMinus);
|
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_SLASH, GHOST_kKeySlash);
|
||||||
GXMAP(type,SDL_SCANCODE_BACKSLASH, GHOST_kKeyBackslash);
|
GXMAP(type,SDL_SCANCODE_BACKSLASH, GHOST_kKeyBackslash);
|
||||||
GXMAP(type,SDL_SCANCODE_KP_EQUALS, GHOST_kKeyEqual);
|
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_RCTRL, GHOST_kKeyRightControl);
|
||||||
GXMAP(type,SDL_SCANCODE_LALT, GHOST_kKeyLeftAlt);
|
GXMAP(type,SDL_SCANCODE_LALT, GHOST_kKeyLeftAlt);
|
||||||
GXMAP(type,SDL_SCANCODE_RALT, GHOST_kKeyRightAlt);
|
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_RGUI, GHOST_kKeyOS);
|
||||||
|
|
||||||
GXMAP(type,SDL_SCANCODE_INSERT, GHOST_kKeyInsert);
|
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_CAPSLOCK, GHOST_kKeyCapsLock);
|
||||||
GXMAP(type,SDL_SCANCODE_SCROLLLOCK, GHOST_kKeyScrollLock);
|
GXMAP(type,SDL_SCANCODE_SCROLLLOCK, GHOST_kKeyScrollLock);
|
||||||
GXMAP(type,SDL_SCANCODE_NUMLOCKCLEAR, GHOST_kKeyNumLock);
|
GXMAP(type,SDL_SCANCODE_NUMLOCKCLEAR, GHOST_kKeyNumLock);
|
||||||
|
GXMAP(type,SDL_SCANCODE_PRINTSCREEN, GHOST_kKeyPrintScreen);
|
||||||
|
|
||||||
/* keypad events */
|
/* keypad events */
|
||||||
|
|
||||||
@@ -228,6 +232,7 @@ convertSDLKey(SDL_Scancode key)
|
|||||||
GXMAP(type,SDL_SCANCODE_AUDIONEXT, GHOST_kKeyMediaLast);
|
GXMAP(type,SDL_SCANCODE_AUDIONEXT, GHOST_kKeyMediaLast);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
printf("Unknown\n");
|
||||||
type= GHOST_kKeyUnknown;
|
type= GHOST_kKeyUnknown;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -372,6 +377,7 @@ GHOST_SystemSDL::processEvent(SDL_Event *sdl_event)
|
|||||||
case SDL_KEYUP:
|
case SDL_KEYUP:
|
||||||
{
|
{
|
||||||
SDL_KeyboardEvent &sdl_sub_evt= sdl_event->key;
|
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_TEventType type= (sdl_sub_evt.state == SDL_PRESSED) ? GHOST_kEventKeyDown : GHOST_kEventKeyUp;
|
||||||
|
|
||||||
GHOST_WindowSDL *window= findGhostWindow(SDL_GetWindowFromID(sdl_sub_evt.windowID));
|
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);
|
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 */
|
/* 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;
|
break;
|
||||||
}
|
}
|
||||||
|
@@ -39,22 +39,20 @@
|
|||||||
* @date May 7, 2001
|
* @date May 7, 2001
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef BF_GHOST_DEBUG
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#ifdef FREE_WINDOWS
|
|
||||||
# define WINVER 0x0501 /* GetConsoleWindow() for MinGW */
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h> // [mce] temporary debug, remove soon!
|
||||||
|
|
||||||
#include "GHOST_SystemWin32.h"
|
#include "GHOST_SystemWin32.h"
|
||||||
#include "GHOST_EventDragnDrop.h"
|
#include "GHOST_EventDragnDrop.h"
|
||||||
|
|
||||||
#define WIN32_LEAN_AND_MEAN
|
#ifndef _WIN32_IE
|
||||||
#ifdef _WIN32_IE
|
#define _WIN32_IE 0x0501 /* shipped before XP, so doesn't impose additional requirements */
|
||||||
#undef _WIN32_IE
|
|
||||||
#endif
|
#endif
|
||||||
#define _WIN32_IE 0x0501
|
|
||||||
#include <windows.h>
|
|
||||||
#include <shlobj.h>
|
#include <shlobj.h>
|
||||||
|
#include <tlhelp32.h>
|
||||||
|
|
||||||
// win64 doesn't define GWL_USERDATA
|
// win64 doesn't define GWL_USERDATA
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
@@ -64,48 +62,19 @@
|
|||||||
#endif
|
#endif
|
||||||
#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_DisplayManagerWin32.h"
|
||||||
#include "GHOST_EventButton.h"
|
#include "GHOST_EventButton.h"
|
||||||
#include "GHOST_EventCursor.h"
|
#include "GHOST_EventCursor.h"
|
||||||
#include "GHOST_EventKey.h"
|
#include "GHOST_EventKey.h"
|
||||||
#include "GHOST_EventWheel.h"
|
#include "GHOST_EventWheel.h"
|
||||||
#include "GHOST_EventNDOF.h"
|
|
||||||
#include "GHOST_TimerTask.h"
|
#include "GHOST_TimerTask.h"
|
||||||
#include "GHOST_TimerManager.h"
|
#include "GHOST_TimerManager.h"
|
||||||
#include "GHOST_WindowManager.h"
|
#include "GHOST_WindowManager.h"
|
||||||
#include "GHOST_WindowWin32.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
|
// Key code values not found in winuser.h
|
||||||
#ifndef VK_MINUS
|
#ifndef VK_MINUS
|
||||||
@@ -158,18 +127,35 @@
|
|||||||
#define VK_MEDIA_PLAY_PAUSE 0xB3
|
#define VK_MEDIA_PLAY_PAUSE 0xB3
|
||||||
#endif // VK_MEDIA_PLAY_PAUSE
|
#endif // VK_MEDIA_PLAY_PAUSE
|
||||||
|
|
||||||
/*
|
static void initRawInput()
|
||||||
Initiates WM_INPUT messages from keyboard
|
|
||||||
That way GHOST can retrieve true keys
|
|
||||||
*/
|
|
||||||
GHOST_TInt32 GHOST_SystemWin32::initKeyboardRawInput(void)
|
|
||||||
{
|
{
|
||||||
RAWINPUTDEVICE device = {0};
|
#ifdef WITH_INPUT_NDOF
|
||||||
device.usUsagePage = 0x01; /* usUsagePage & usUsage for keyboard*/
|
#define DEVICE_COUNT 2
|
||||||
device.usUsage = 0x06; /* http://msdn.microsoft.com/en-us/windows/hardware/gg487473.aspx */
|
#else
|
||||||
|
#define DEVICE_COUNT 1
|
||||||
|
#endif
|
||||||
|
|
||||||
return RegisterRawInputDevices(&device, 1, sizeof(device));
|
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 */
|
||||||
|
|
||||||
|
#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()
|
GHOST_SystemWin32::GHOST_SystemWin32()
|
||||||
: m_hasPerformanceCounter(false), m_freq(0), m_start(0)
|
: m_hasPerformanceCounter(false), m_freq(0), m_start(0)
|
||||||
@@ -186,6 +172,10 @@ GHOST_SystemWin32::GHOST_SystemWin32()
|
|||||||
this->handleKeyboardChange();
|
this->handleKeyboardChange();
|
||||||
// Require COM for GHOST_DropTargetWin32 created in GHOST_WindowWin32.
|
// Require COM for GHOST_DropTargetWin32 created in GHOST_WindowWin32.
|
||||||
OleInitialize(0);
|
OleInitialize(0);
|
||||||
|
|
||||||
|
#ifdef WITH_INPUT_NDOF
|
||||||
|
m_ndofManager = new GHOST_NDOFManagerWin32(*this);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
GHOST_SystemWin32::~GHOST_SystemWin32()
|
GHOST_SystemWin32::~GHOST_SystemWin32()
|
||||||
@@ -244,6 +234,7 @@ GHOST_IWindow* GHOST_SystemWin32::createWindow(
|
|||||||
// Store the pointer to the window
|
// Store the pointer to the window
|
||||||
// if (state != GHOST_kWindowStateFullScreen) {
|
// if (state != GHOST_kWindowStateFullScreen) {
|
||||||
m_windowManager->addWindow(window);
|
m_windowManager->addWindow(window);
|
||||||
|
m_windowManager->setActiveWindow(window);
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -384,22 +375,15 @@ GHOST_TSuccess GHOST_SystemWin32::init()
|
|||||||
GHOST_TSuccess success = GHOST_System::init();
|
GHOST_TSuccess success = GHOST_System::init();
|
||||||
|
|
||||||
/* Disable scaling on high DPI displays on Vista */
|
/* Disable scaling on high DPI displays on Vista */
|
||||||
|
HMODULE
|
||||||
user32 = ::LoadLibraryA("user32.dll");
|
user32 = ::LoadLibraryA("user32.dll");
|
||||||
typedef BOOL (WINAPI * LPFNSETPROCESSDPIAWARE)();
|
typedef BOOL (WINAPI * LPFNSETPROCESSDPIAWARE)();
|
||||||
LPFNSETPROCESSDPIAWARE SetProcessDPIAware =
|
LPFNSETPROCESSDPIAWARE SetProcessDPIAware =
|
||||||
(LPFNSETPROCESSDPIAWARE)GetProcAddress(user32, "SetProcessDPIAware");
|
(LPFNSETPROCESSDPIAWARE)GetProcAddress(user32, "SetProcessDPIAware");
|
||||||
if (SetProcessDPIAware)
|
if (SetProcessDPIAware)
|
||||||
SetProcessDPIAware();
|
SetProcessDPIAware();
|
||||||
#ifdef NEED_RAW_PROC
|
|
||||||
pRegisterRawInputDevices = (LPFNDLLRRID)GetProcAddress(user32, "RegisterRawInputDevices");
|
|
||||||
pGetRawInputData = (LPFNDLLGRID)GetProcAddress(user32, "GetRawInputData");
|
|
||||||
#else
|
|
||||||
FreeLibrary(user32);
|
FreeLibrary(user32);
|
||||||
#endif
|
initRawInput();
|
||||||
|
|
||||||
/* Initiates WM_INPUT messages from keyboard */
|
|
||||||
initKeyboardRawInput();
|
|
||||||
|
|
||||||
|
|
||||||
// Determine whether this system has a high frequency performance counter. */
|
// Determine whether this system has a high frequency performance counter. */
|
||||||
m_hasPerformanceCounter = ::QueryPerformanceFrequency((LARGE_INTEGER*)&m_freq) == TRUE;
|
m_hasPerformanceCounter = ::QueryPerformanceFrequency((LARGE_INTEGER*)&m_freq) == TRUE;
|
||||||
@@ -440,41 +424,25 @@ GHOST_TSuccess GHOST_SystemWin32::init()
|
|||||||
|
|
||||||
GHOST_TSuccess GHOST_SystemWin32::exit()
|
GHOST_TSuccess GHOST_SystemWin32::exit()
|
||||||
{
|
{
|
||||||
#ifdef NEED_RAW_PROC
|
|
||||||
FreeLibrary(user32);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return GHOST_System::exit();
|
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;
|
GHOST_TKey key = GHOST_kKeyUnknown;
|
||||||
|
|
||||||
|
|
||||||
if(!keyDown)
|
if(!keyDown)
|
||||||
return GHOST_kKeyUnknown;
|
return GHOST_kKeyUnknown;
|
||||||
|
|
||||||
GetRawInputData((HRAWINPUT)lParam, RID_INPUT, 0, &size, sizeof(RAWINPUTHEADER));
|
|
||||||
|
|
||||||
|
|
||||||
if((data = (char*)malloc(size)) &&
|
|
||||||
GetRawInputData((HRAWINPUT)lParam, RID_INPUT, data, &size, sizeof(RAWINPUTHEADER)))
|
|
||||||
{
|
|
||||||
RAWINPUT ri;
|
|
||||||
memcpy(&ri,data,(size < sizeof(ri)) ? size : sizeof(ri));
|
|
||||||
|
|
||||||
if (ri.header.dwType == RIM_TYPEKEYBOARD)
|
|
||||||
{
|
|
||||||
GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem();
|
GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem();
|
||||||
|
|
||||||
GHOST_ModifierKeys modifiers;
|
GHOST_ModifierKeys modifiers;
|
||||||
system->retrieveModifierKeys(modifiers);
|
system->retrieveModifierKeys(modifiers);
|
||||||
|
|
||||||
*keyDown = !(ri.data.keyboard.Flags & RI_KEY_BREAK);
|
*keyDown = !(raw.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)));
|
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
|
// extra handling of modifier keys: don't send repeats out from GHOST
|
||||||
if(key >= GHOST_kKeyLeftShift && key <= GHOST_kKeyRightAlt)
|
if(key >= GHOST_kKeyLeftShift && key <= GHOST_kKeyRightAlt)
|
||||||
@@ -533,11 +501,7 @@ GHOST_TKey GHOST_SystemWin32::hardKey(GHOST_IWindow *window, WPARAM wParam, LPAR
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if(vk) *vk = ri.data.keyboard.VKey;
|
if(vk) *vk = raw.data.keyboard.VKey;
|
||||||
};
|
|
||||||
|
|
||||||
};
|
|
||||||
free(data);
|
|
||||||
|
|
||||||
return key;
|
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;
|
int keyDown=0;
|
||||||
char vk;
|
char vk;
|
||||||
GHOST_SystemWin32 * system = (GHOST_SystemWin32 *)getSystem();
|
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;
|
GHOST_EventKey* event;
|
||||||
if (key != GHOST_kKeyUnknown) {
|
if (key != GHOST_kKeyUnknown) {
|
||||||
char ascii = '\0';
|
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)
|
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,
|
GHOST_TSuccess GHOST_SystemWin32::pushDragDropEvent(GHOST_TEventType eventType,
|
||||||
@@ -799,9 +769,95 @@ void GHOST_SystemWin32::processMinMaxInfo(MINMAXINFO * minmax)
|
|||||||
minmax->ptMinTrackSize.y=240;
|
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)
|
LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
GHOST_Event* event = 0;
|
GHOST_Event* event = 0;
|
||||||
|
bool eventHandled = false;
|
||||||
|
|
||||||
LRESULT lResult = 0;
|
LRESULT lResult = 0;
|
||||||
GHOST_SystemWin32* system = ((GHOST_SystemWin32*)getSystem());
|
GHOST_SystemWin32* system = ((GHOST_SystemWin32*)getSystem());
|
||||||
GHOST_ASSERT(system, "GHOST_SystemWin32::s_wndProc(): system not initialized")
|
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
|
// Keyboard events, processed
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
case WM_INPUT:
|
case WM_INPUT:
|
||||||
|
{
|
||||||
// check WM_INPUT from input sink when ghost window is not in the foreground
|
// check WM_INPUT from input sink when ghost window is not in the foreground
|
||||||
if (wParam == RIM_INPUTSINK) {
|
if (wParam == RIM_INPUTSINK) {
|
||||||
if (GetFocus() != hwnd) // WM_INPUT message not for this window
|
if (GetFocus() != hwnd) // WM_INPUT message not for this window
|
||||||
return 0;
|
return 0;
|
||||||
} //else wPAram == RIM_INPUT
|
} //else wParam == RIM_INPUT
|
||||||
event = processKeyEvent(window, wParam, lParam);
|
|
||||||
|
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) {
|
if (!event) {
|
||||||
GHOST_PRINT("GHOST_SystemWin32::wndProc: key event ")
|
GHOST_PRINT("GHOST_SystemWin32::wndProc: key event ")
|
||||||
GHOST_PRINT(msg)
|
GHOST_PRINT(msg)
|
||||||
GHOST_PRINT(" key ignored\n")
|
GHOST_PRINT(" key ignored\n")
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
#ifdef WITH_INPUT_NDOF
|
||||||
|
case RIM_TYPEHID:
|
||||||
|
if (system->processNDOF(raw))
|
||||||
|
eventHandled = true;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
// Keyboard events, ignored
|
// Keyboard events, ignored
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
@@ -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,
|
* 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.
|
* 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);
|
event = processWindowEvent(LOWORD(wParam) ? GHOST_kEventWindowActivate : GHOST_kEventWindowDeactivate, window);
|
||||||
/* WARNING: Let DefWindowProc handle WM_ACTIVATE, otherwise WM_MOUSEWHEEL
|
/* WARNING: Let DefWindowProc handle WM_ACTIVATE, otherwise WM_MOUSEWHEEL
|
||||||
will not be dispatched to OUR active window if we minimize one of OUR windows. */
|
will not be dispatched to OUR active window if we minimize one of OUR windows. */
|
||||||
lResult = ::DefWindowProc(hwnd, msg, wParam, lParam);
|
lResult = ::DefWindowProc(hwnd, msg, wParam, lParam);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case WM_PAINT:
|
case WM_PAINT:
|
||||||
/* An application sends the WM_PAINT message when the system or another application
|
/* 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
|
* 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.
|
* In GHOST, we let DefWindowProc call the timer callback.
|
||||||
*/
|
*/
|
||||||
break;
|
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 {
|
else {
|
||||||
@@ -1165,10 +1224,12 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
|
|||||||
|
|
||||||
if (event) {
|
if (event) {
|
||||||
system->pushEvent(event);
|
system->pushEvent(event);
|
||||||
|
eventHandled = true;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
|
if (!eventHandled)
|
||||||
lResult = ::DefWindowProc(hwnd, msg, wParam, lParam);
|
lResult = ::DefWindowProc(hwnd, msg, wParam, lParam);
|
||||||
}
|
|
||||||
return lResult;
|
return lResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1237,8 +1298,32 @@ int GHOST_SystemWin32::toggleConsole(int action)
|
|||||||
{
|
{
|
||||||
case 3: //hide if no console
|
case 3: //hide if no console
|
||||||
{
|
{
|
||||||
CONSOLE_SCREEN_BUFFER_INFO csbi = {{0}};
|
DWORD sp = GetCurrentProcessId();
|
||||||
if(!GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi) || csbi.dwCursorPosition.X || csbi.dwCursorPosition.Y>1)
|
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;
|
break;
|
||||||
}
|
}
|
||||||
case 0: //hide
|
case 0: //hide
|
||||||
|
@@ -38,7 +38,10 @@
|
|||||||
#error WIN32 only!
|
#error WIN32 only!
|
||||||
#endif // WIN32
|
#endif // WIN32
|
||||||
|
|
||||||
|
#define _WIN32_WINNT 0x501 // require Windows XP or newer
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#include <ole2.h> // for drag-n-drop
|
||||||
|
|
||||||
#include "GHOST_System.h"
|
#include "GHOST_System.h"
|
||||||
|
|
||||||
@@ -46,95 +49,6 @@
|
|||||||
# define __int64 long long
|
# define __int64 long long
|
||||||
#endif
|
#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_EventButton;
|
||||||
class GHOST_EventCursor;
|
class GHOST_EventCursor;
|
||||||
class GHOST_EventKey;
|
class GHOST_EventKey;
|
||||||
@@ -314,14 +228,13 @@ protected:
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Catches raw WIN32 key codes from WM_INPUT in the wndproc.
|
* Catches raw WIN32 key codes from WM_INPUT in the wndproc.
|
||||||
* @param window-> The window for this handling
|
* @param window The window for this handling
|
||||||
* @param wParam The wParam from the wndproc
|
* @param raw RawInput structure with detailed info about the key event
|
||||||
* @param lParam The lParam from the wndproc
|
|
||||||
* @param keyDown Pointer flag that specify if a key is down
|
* @param keyDown Pointer flag that specify if a key is down
|
||||||
* @param vk Pointer to virtual key
|
* @param vk Pointer to virtual key
|
||||||
* @return The GHOST key (GHOST_kKeyUnknown if no match).
|
* @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).
|
* 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.
|
* In most cases this is a straightforward conversion of key codes.
|
||||||
* For the modifier keys however, we want to distinguish left and right keys.
|
* For the modifier keys however, we want to distinguish left and right keys.
|
||||||
* @param window The window receiving the event (the active window).
|
* @param window The window receiving the event (the active window).
|
||||||
* @param wParam The wParam from the wndproc
|
* @param raw RawInput structure with detailed info about the key event
|
||||||
* @param lParam The lParam from the wndproc
|
|
||||||
*/
|
*/
|
||||||
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
|
* Process special keys (VK_OEM_*), to see if current key layout
|
||||||
@@ -383,12 +295,24 @@ protected:
|
|||||||
* @return The event created.
|
* @return The event created.
|
||||||
*/
|
*/
|
||||||
static GHOST_Event* processWindowEvent(GHOST_TEventType type, GHOST_IWindow* window);
|
static GHOST_Event* processWindowEvent(GHOST_TEventType type, GHOST_IWindow* window);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles minimum window size.
|
* Handles minimum window size.
|
||||||
* @param minmax The MINMAXINFO structure.
|
* @param minmax The MINMAXINFO structure.
|
||||||
*/
|
*/
|
||||||
static void processMinMaxInfo(MINMAXINFO * minmax);
|
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).
|
* Returns the local state of the modifier keys (from the message queue).
|
||||||
* @param keys The state of the keys.
|
* @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);
|
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
|
* Toggles console
|
||||||
* @action 0 - Hides
|
* @action 0 - Hides
|
||||||
@@ -445,15 +364,6 @@ protected:
|
|||||||
|
|
||||||
/** Console status */
|
/** Console status */
|
||||||
int m_consoleStatus;
|
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
|
inline void GHOST_SystemWin32::retrieveModifierKeys(GHOST_ModifierKeys& keys) const
|
||||||
@@ -487,4 +397,3 @@ inline void GHOST_SystemWin32::handleKeyboardChange(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // _GHOST_SYSTEM_WIN32_H_
|
#endif // _GHOST_SYSTEM_WIN32_H_
|
||||||
|
|
||||||
|
@@ -42,9 +42,10 @@
|
|||||||
#include "GHOST_EventKey.h"
|
#include "GHOST_EventKey.h"
|
||||||
#include "GHOST_EventButton.h"
|
#include "GHOST_EventButton.h"
|
||||||
#include "GHOST_EventWheel.h"
|
#include "GHOST_EventWheel.h"
|
||||||
#include "GHOST_EventNDOF.h"
|
|
||||||
#include "GHOST_NDOFManager.h"
|
|
||||||
#include "GHOST_DisplayManagerX11.h"
|
#include "GHOST_DisplayManagerX11.h"
|
||||||
|
#ifdef WITH_INPUT_NDOF
|
||||||
|
#include "GHOST_NDOFManagerX11.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "GHOST_Debug.h"
|
#include "GHOST_Debug.h"
|
||||||
|
|
||||||
@@ -79,19 +80,6 @@
|
|||||||
static GHOST_TKey
|
static GHOST_TKey
|
||||||
convertXKey(KeySym key);
|
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
|
//these are for copy and select copy
|
||||||
static char *txt_cut_buffer= NULL;
|
static char *txt_cut_buffer= NULL;
|
||||||
static char *txt_select_buffer= NULL;
|
static char *txt_select_buffer= NULL;
|
||||||
@@ -181,6 +169,9 @@ init(
|
|||||||
GHOST_TSuccess success = GHOST_System::init();
|
GHOST_TSuccess success = GHOST_System::init();
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
|
#ifdef WITH_INPUT_NDOF
|
||||||
|
m_ndofManager = new GHOST_NDOFManagerX11(*this);
|
||||||
|
#endif
|
||||||
m_displayManager = new GHOST_DisplayManagerX11(this);
|
m_displayManager = new GHOST_DisplayManagerX11(this);
|
||||||
|
|
||||||
if (m_displayManager) {
|
if (m_displayManager) {
|
||||||
@@ -275,7 +266,7 @@ createWindow(
|
|||||||
if (window->getValid()) {
|
if (window->getValid()) {
|
||||||
// Store the pointer to the window
|
// Store the pointer to the window
|
||||||
m_windowManager->addWindow(window);
|
m_windowManager->addWindow(window);
|
||||||
|
m_windowManager->setActiveWindow(window);
|
||||||
pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window) );
|
pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window) );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -386,8 +377,6 @@ lastEventTime(Time default_time) {
|
|||||||
return data.timestamp;
|
return data.timestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
GHOST_SystemX11::
|
GHOST_SystemX11::
|
||||||
processEvents(
|
processEvents(
|
||||||
@@ -428,6 +417,13 @@ processEvents(
|
|||||||
if (generateWindowExposeEvents()) {
|
if (generateWindowExposeEvents()) {
|
||||||
anyProcessed = true;
|
anyProcessed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WITH_INPUT_NDOF
|
||||||
|
if (dynamic_cast<GHOST_NDOFManagerX11*>(m_ndofManager)->processEvents()) {
|
||||||
|
anyProcessed = true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
} while (waitForEvent && !anyProcessed);
|
} while (waitForEvent && !anyProcessed);
|
||||||
|
|
||||||
return anyProcessed;
|
return anyProcessed;
|
||||||
@@ -612,6 +608,9 @@ GHOST_SystemX11::processEvent(XEvent *xe)
|
|||||||
{
|
{
|
||||||
XFocusChangeEvent &xfe = xe->xfocus;
|
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
|
// May have to look at the type of event and filter some
|
||||||
// out.
|
// out.
|
||||||
|
|
||||||
@@ -641,32 +640,8 @@ GHOST_SystemX11::processEvent(XEvent *xe)
|
|||||||
);
|
);
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
if (sNdofInfo.currValues) {
|
|
||||||
static GHOST_TEventNDOFData data = {0,0,0,0,0,0,0,0,0,0,0};
|
if (((Atom)xcme.data.l[0]) == m_wm_take_focus) {
|
||||||
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) {
|
|
||||||
XWindowAttributes attr;
|
XWindowAttributes attr;
|
||||||
Window fwin;
|
Window fwin;
|
||||||
int revert_to;
|
int revert_to;
|
||||||
@@ -723,6 +698,14 @@ GHOST_SystemX11::processEvent(XEvent *xe)
|
|||||||
xce.y_root
|
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;
|
break;
|
||||||
}
|
}
|
||||||
case MapNotify:
|
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_TSuccess
|
||||||
GHOST_SystemX11::
|
GHOST_SystemX11::
|
||||||
getModifierKeys(
|
getModifierKeys(
|
||||||
|
@@ -203,11 +203,6 @@ public:
|
|||||||
return m_display;
|
return m_display;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
|
||||||
prepareNdofInfo(
|
|
||||||
volatile GHOST_TEventNDOFData *current_values
|
|
||||||
);
|
|
||||||
|
|
||||||
/* Helped function for get data from the clipboard. */
|
/* Helped function for get data from the clipboard. */
|
||||||
void getClipboard_xcout(XEvent evt, Atom sel, Atom target,
|
void getClipboard_xcout(XEvent evt, Atom sel, Atom target,
|
||||||
unsigned char **txt, unsigned long *len,
|
unsigned char **txt, unsigned long *len,
|
||||||
|
@@ -3,20 +3,16 @@
|
|||||||
*/
|
*/
|
||||||
#ifndef GHOST_TASKBARWIN32_H_
|
#ifndef GHOST_TASKBARWIN32_H_
|
||||||
#define GHOST_TASKBARWIN32_H_
|
#define GHOST_TASKBARWIN32_H_
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
#error WIN32 only!
|
#error WIN32 only!
|
||||||
#endif // WIN32
|
#endif // WIN32
|
||||||
|
|
||||||
|
#define _WIN32_WINNT 0x501 // require Windows XP or newer
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <shlobj.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.
|
// 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
|
// Note, ITaskbarList3 is supported only since Windows 7, though. Check for that is done in
|
||||||
|
@@ -39,20 +39,12 @@
|
|||||||
#endif // WIN32
|
#endif // WIN32
|
||||||
|
|
||||||
#include "GHOST_Window.h"
|
#include "GHOST_Window.h"
|
||||||
|
|
||||||
/* MinGW needs it */
|
|
||||||
#ifdef FREE_WINDOWS
|
|
||||||
#ifdef WINVER
|
|
||||||
#undef WINVER
|
|
||||||
#endif
|
|
||||||
#define WINVER 0x0501
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
#include "GHOST_TaskbarWin32.h"
|
#include "GHOST_TaskbarWin32.h"
|
||||||
|
|
||||||
|
#define _WIN32_WINNT 0x501 // require Windows XP or newer
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
|
||||||
#include <wintab.h>
|
#include <wintab.h>
|
||||||
#define PACKETDATA (PK_BUTTONS | PK_NORMAL_PRESSURE | PK_ORIENTATION | PK_CURSOR)
|
#define PACKETDATA (PK_BUTTONS | PK_NORMAL_PRESSURE | PK_ORIENTATION | PK_CURSOR)
|
||||||
|
@@ -16,7 +16,7 @@
|
|||||||
#
|
#
|
||||||
# ##### END GPL LICENSE BLOCK #####
|
# ##### END GPL LICENSE BLOCK #####
|
||||||
|
|
||||||
# <pep8 compliant>
|
# <pep8-80 compliant>
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
"paths",
|
"paths",
|
||||||
@@ -26,12 +26,14 @@ __all__ = (
|
|||||||
"disable",
|
"disable",
|
||||||
"reset_all",
|
"reset_all",
|
||||||
"module_bl_info",
|
"module_bl_info",
|
||||||
)
|
)
|
||||||
|
|
||||||
import bpy as _bpy
|
import bpy as _bpy
|
||||||
|
|
||||||
|
|
||||||
error_duplicates = False
|
error_duplicates = False
|
||||||
|
error_encoding = False
|
||||||
|
|
||||||
|
|
||||||
def paths():
|
def paths():
|
||||||
# RELEASE SCRIPTS: official scripts distributed in Blender releases
|
# RELEASE SCRIPTS: official scripts distributed in Blender releases
|
||||||
@@ -50,14 +52,18 @@ def paths():
|
|||||||
|
|
||||||
def modules(module_cache):
|
def modules(module_cache):
|
||||||
global error_duplicates
|
global error_duplicates
|
||||||
|
global error_encoding
|
||||||
import os
|
import os
|
||||||
|
|
||||||
error_duplicates = False
|
error_duplicates = False
|
||||||
|
error_encoding = False
|
||||||
|
|
||||||
path_list = paths()
|
path_list = paths()
|
||||||
|
|
||||||
# fake module importing
|
# fake module importing
|
||||||
def fake_module(mod_name, mod_path, speedy=True):
|
def fake_module(mod_name, mod_path, speedy=True):
|
||||||
|
global error_encoding
|
||||||
|
|
||||||
if _bpy.app.debug:
|
if _bpy.app.debug:
|
||||||
print("fake_module", mod_path, mod_name)
|
print("fake_module", mod_path, mod_name)
|
||||||
import ast
|
import ast
|
||||||
@@ -68,12 +74,28 @@ def modules(module_cache):
|
|||||||
line_iter = iter(file_mod)
|
line_iter = iter(file_mod)
|
||||||
l = ""
|
l = ""
|
||||||
while not l.startswith("bl_info"):
|
while not l.startswith("bl_info"):
|
||||||
|
try:
|
||||||
l = line_iter.readline()
|
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:
|
if len(l) == 0:
|
||||||
break
|
break
|
||||||
while l.rstrip():
|
while l.rstrip():
|
||||||
lines.append(l)
|
lines.append(l)
|
||||||
|
try:
|
||||||
l = line_iter.readline()
|
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)
|
data = "".join(lines)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
@@ -128,7 +150,12 @@ def modules(module_cache):
|
|||||||
error_duplicates = True
|
error_duplicates = True
|
||||||
|
|
||||||
elif mod.__time__ != os.path.getmtime(mod_path):
|
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]
|
del module_cache[mod_name]
|
||||||
mod = None
|
mod = None
|
||||||
|
|
||||||
@@ -143,7 +170,9 @@ def modules(module_cache):
|
|||||||
del modules_stale
|
del modules_stale
|
||||||
|
|
||||||
mod_list = list(module_cache.values())
|
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
|
return mod_list
|
||||||
|
|
||||||
|
|
||||||
@@ -163,8 +192,9 @@ def check(module_name):
|
|||||||
loaded_state = mod and getattr(mod, "__addon_enabled__", Ellipsis)
|
loaded_state = mod and getattr(mod, "__addon_enabled__", Ellipsis)
|
||||||
|
|
||||||
if loaded_state is Ellipsis:
|
if loaded_state is Ellipsis:
|
||||||
print("Warning: addon-module %r found module but without"
|
print("Warning: addon-module %r found module "
|
||||||
" __addon_enabled__ field, possible name collision from file: %r" %
|
"but without __addon_enabled__ field, "
|
||||||
|
"possible name collision from file: %r" %
|
||||||
(module_name, getattr(mod, "__file__", "<unknown>")))
|
(module_name, getattr(mod, "__file__", "<unknown>")))
|
||||||
|
|
||||||
loaded_state = False
|
loaded_state = False
|
||||||
@@ -207,7 +237,8 @@ def enable(module_name, default_set=True):
|
|||||||
return None
|
return None
|
||||||
mod.__addon_enabled__ = False
|
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
|
# 1) try import
|
||||||
try:
|
try:
|
||||||
mod = __import__(module_name)
|
mod = __import__(module_name)
|
||||||
@@ -254,8 +285,9 @@ def disable(module_name, default_set=True):
|
|||||||
import sys
|
import sys
|
||||||
mod = sys.modules.get(module_name)
|
mod = sys.modules.get(module_name)
|
||||||
|
|
||||||
# possible this addon is from a previous session and didnt load a module this time.
|
# possible this addon is from a previous session and didnt load a
|
||||||
# so even if the module is not found, still disable the addon in the user prefs.
|
# module this time. So even if the module is not found, still disable
|
||||||
|
# the addon in the user prefs.
|
||||||
if mod:
|
if mod:
|
||||||
mod.__addon_enabled__ = False
|
mod.__addon_enabled__ = False
|
||||||
|
|
||||||
@@ -310,7 +342,22 @@ def reset_all(reload_scripts=False):
|
|||||||
disable(mod_name)
|
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", {})
|
addon_info = getattr(mod, "bl_info", {})
|
||||||
|
|
||||||
# avoid re-initializing
|
# avoid re-initializing
|
||||||
|
@@ -16,7 +16,7 @@
|
|||||||
#
|
#
|
||||||
# ##### END GPL LICENSE BLOCK #####
|
# ##### END GPL LICENSE BLOCK #####
|
||||||
|
|
||||||
# <pep8 compliant>
|
# <pep8-80 compliant>
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Give access to blender data and utility functions.
|
Give access to blender data and utility functions.
|
||||||
@@ -31,7 +31,7 @@ __all__ = (
|
|||||||
"props",
|
"props",
|
||||||
"types",
|
"types",
|
||||||
"utils",
|
"utils",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
# internal blender C module
|
# internal blender C module
|
||||||
@@ -43,12 +43,14 @@ from . import utils, path, ops
|
|||||||
# fake operator module
|
# fake operator module
|
||||||
ops = ops.ops_fake_module
|
ops = ops.ops_fake_module
|
||||||
|
|
||||||
|
|
||||||
def _main():
|
def _main():
|
||||||
import sys as _sys
|
import sys as _sys
|
||||||
|
|
||||||
# Possibly temp. addons path
|
# Possibly temp. addons path
|
||||||
from os.path import join, dirname, normpath
|
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 "-d" in sys.argv: # Enable this to measure startup speed
|
||||||
if 0:
|
if 0:
|
||||||
|
@@ -16,26 +16,44 @@
|
|||||||
#
|
#
|
||||||
# ##### END GPL LICENSE BLOCK #####
|
# ##### END GPL LICENSE BLOCK #####
|
||||||
|
|
||||||
# <pep8 compliant>
|
# <pep8-80 compliant>
|
||||||
|
|
||||||
"""
|
"""
|
||||||
This module has a similar scope to os.path, containing utility
|
This module has a similar scope to os.path, containing utility
|
||||||
functions for dealing with paths in Blender.
|
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 bpy as _bpy
|
||||||
import os as _os
|
import os as _os
|
||||||
|
|
||||||
|
|
||||||
def abspath(path, start=None):
|
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
|
:type start: string
|
||||||
"""
|
"""
|
||||||
if path.startswith("//"):
|
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
|
return path
|
||||||
|
|
||||||
@@ -44,7 +62,8 @@ def relpath(path, start=None):
|
|||||||
"""
|
"""
|
||||||
Returns the path relative to the current blend file using the "//" prefix.
|
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
|
:type start: string
|
||||||
"""
|
"""
|
||||||
if not path.startswith("//"):
|
if not path.startswith("//"):
|
||||||
@@ -68,27 +87,28 @@ def is_subdir(path, directory):
|
|||||||
|
|
||||||
def clean_name(name, replace="_"):
|
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 "_"
|
All characters besides A-Z/a-z, 0-9 are replaced with "_"
|
||||||
or the replace argument if defined.
|
or the replace argument if defined.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
unclean_chars = \
|
bad_chars = ("\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e"
|
||||||
"\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"
|
||||||
\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"
|
||||||
\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"
|
||||||
\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"
|
||||||
\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"
|
||||||
\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"
|
||||||
\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"
|
||||||
\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"
|
||||||
\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"
|
||||||
\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"
|
||||||
\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"
|
||||||
\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")
|
||||||
\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe"
|
|
||||||
|
|
||||||
for ch in unclean_chars:
|
for ch in bad_chars:
|
||||||
name = name.replace(ch, replace)
|
name = name.replace(ch, replace)
|
||||||
return name
|
return name
|
||||||
|
|
||||||
@@ -96,8 +116,9 @@ def clean_name(name, replace="_"):
|
|||||||
def display_name(name):
|
def display_name(name):
|
||||||
"""
|
"""
|
||||||
Creates a display string from name to be used menus and the user interface.
|
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.
|
Capitalize the first letter in all lowercase names,
|
||||||
Intended for use with filenames and module names.
|
mixed case names are kept as is. Intended for use with
|
||||||
|
filenames and module names.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
name_base = _os.path.splitext(name)[0]
|
name_base = _os.path.splitext(name)[0]
|
||||||
@@ -115,9 +136,11 @@ def display_name(name):
|
|||||||
|
|
||||||
def display_name_from_filepath(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):
|
def resolve_ncase(path):
|
||||||
@@ -132,7 +155,8 @@ def resolve_ncase(path):
|
|||||||
if not path or os.path.exists(path):
|
if not path or os.path.exists(path):
|
||||||
return path, True
|
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)
|
dirpath = os.path.dirname(path)
|
||||||
|
|
||||||
suffix = path[:0] # "" but ensure byte/str match
|
suffix = path[:0] # "" but ensure byte/str match
|
||||||
@@ -180,7 +204,7 @@ def resolve_ncase(path):
|
|||||||
|
|
||||||
def ensure_ext(filepath, ext, case_sensitive=False):
|
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.
|
:arg ext: The extension to check for.
|
||||||
:type ext: string
|
:type ext: string
|
||||||
@@ -190,7 +214,9 @@ def ensure_ext(filepath, ext, case_sensitive=False):
|
|||||||
import os
|
import os
|
||||||
fn_base, fn_ext = os.path.splitext(filepath)
|
fn_base, fn_ext = os.path.splitext(filepath)
|
||||||
if fn_base and fn_ext:
|
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
|
return filepath
|
||||||
else:
|
else:
|
||||||
return fn_base + ext
|
return fn_base + ext
|
||||||
@@ -228,7 +254,9 @@ def module_names(path, recursive=False):
|
|||||||
modules.append((filename, fullpath))
|
modules.append((filename, fullpath))
|
||||||
if recursive:
|
if recursive:
|
||||||
for mod_name, mod_path in module_names(directory, True):
|
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
|
return modules
|
||||||
|
|
||||||
|
@@ -16,13 +16,33 @@
|
|||||||
#
|
#
|
||||||
# ##### END GPL LICENSE BLOCK #####
|
# ##### END GPL LICENSE BLOCK #####
|
||||||
|
|
||||||
# <pep8 compliant>
|
# <pep8-80 compliant>
|
||||||
|
|
||||||
"""
|
"""
|
||||||
This module contains utility functions specific to blender but
|
This module contains utility functions specific to blender but
|
||||||
not assosiated with blenders internal data.
|
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 register_class, unregister_class, blend_paths, resource_path
|
||||||
from _bpy import script_paths as _bpy_script_paths
|
from _bpy import script_paths as _bpy_script_paths
|
||||||
from _bpy import user_resource as _user_resource
|
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:
|
if module_name in loaded_modules:
|
||||||
return None
|
return None
|
||||||
if "." in module_name:
|
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
|
return None
|
||||||
|
|
||||||
if use_time:
|
if use_time:
|
||||||
@@ -74,7 +95,8 @@ def modules_from_path(path, loaded_modules):
|
|||||||
|
|
||||||
:arg path: this path is scanned for scripts and packages.
|
:arg path: this path is scanned for scripts and packages.
|
||||||
:type path: string
|
: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
|
:type loaded_modules: set
|
||||||
:return: all loaded modules.
|
:return: all loaded modules.
|
||||||
:rtype: list
|
:rtype: list
|
||||||
@@ -97,13 +119,17 @@ def load_scripts(reload_scripts=False, refresh_scripts=False):
|
|||||||
"""
|
"""
|
||||||
Load scripts and run each modules register function.
|
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
|
: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
|
:type refresh_scripts: bool
|
||||||
"""
|
"""
|
||||||
use_time = _bpy.app.debug
|
use_time = _bpy.app.debug
|
||||||
|
|
||||||
|
prefs = _bpy.context.user_preferences
|
||||||
|
|
||||||
if use_time:
|
if use_time:
|
||||||
import time
|
import time
|
||||||
t_main = time.time()
|
t_main = time.time()
|
||||||
@@ -116,10 +142,11 @@ def load_scripts(reload_scripts=False, refresh_scripts=False):
|
|||||||
if reload_scripts:
|
if reload_scripts:
|
||||||
_bpy_types.TypeMap.clear()
|
_bpy_types.TypeMap.clear()
|
||||||
|
|
||||||
# just unload, dont change user defaults, this means we can sync to reload.
|
# just unload, dont change user defaults, this means we can sync
|
||||||
# note that they will only actually reload of the modification time changes.
|
# to reload. note that they will only actually reload of the
|
||||||
# this `wont` work for packages so... its not perfect.
|
# modification time changes. This `wont` work for packages so...
|
||||||
for module_name in [ext.module for ext in _bpy.context.user_preferences.addons]:
|
# its not perfect.
|
||||||
|
for module_name in [ext.module for ext in prefs.addons]:
|
||||||
_addon_utils.disable(module_name, default_set=False)
|
_addon_utils.disable(module_name, default_set=False)
|
||||||
|
|
||||||
def register_module_call(mod):
|
def register_module_call(mod):
|
||||||
@@ -131,7 +158,9 @@ def load_scripts(reload_scripts=False, refresh_scripts=False):
|
|||||||
import traceback
|
import traceback
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
else:
|
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):
|
def unregister_module_call(mod):
|
||||||
unregister = getattr(mod, "unregister", None)
|
unregister = getattr(mod, "unregister", None)
|
||||||
@@ -172,7 +201,8 @@ def load_scripts(reload_scripts=False, refresh_scripts=False):
|
|||||||
if reload_scripts:
|
if reload_scripts:
|
||||||
|
|
||||||
# module names -> modules
|
# 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
|
# loop over and unload all scripts
|
||||||
_global_loaded_modules.reverse()
|
_global_loaded_modules.reverse()
|
||||||
@@ -201,7 +231,8 @@ def load_scripts(reload_scripts=False, refresh_scripts=False):
|
|||||||
_addon_utils.reset_all(reload_scripts)
|
_addon_utils.reset_all(reload_scripts)
|
||||||
|
|
||||||
# run the active integration preset
|
# 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:
|
if filepath:
|
||||||
keyconfig_set(filepath)
|
keyconfig_set(filepath)
|
||||||
|
|
||||||
@@ -214,12 +245,16 @@ def load_scripts(reload_scripts=False, refresh_scripts=False):
|
|||||||
|
|
||||||
|
|
||||||
# base scripts
|
# 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), )
|
_scripts = (_os.path.normpath(_scripts), )
|
||||||
|
|
||||||
|
|
||||||
def user_script_path():
|
def user_script_path():
|
||||||
path = _bpy.context.user_preferences.filepaths.script_directory
|
prefs = _bpy.context.user_preferences
|
||||||
|
path = prefs.filepaths.script_directory
|
||||||
|
|
||||||
if path:
|
if path:
|
||||||
path = _os.path.normpath(path)
|
path = _os.path.normpath(path)
|
||||||
@@ -236,22 +271,25 @@ def script_paths(subdir=None, user_pref=True, all=False):
|
|||||||
:type subdir: string
|
:type subdir: string
|
||||||
:arg user_pref: Include the user preference script path.
|
:arg user_pref: Include the user preference script path.
|
||||||
:type user_pref: bool
|
: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
|
:type all: bool
|
||||||
:return: script paths.
|
:return: script paths.
|
||||||
:rtype: list
|
:rtype: list
|
||||||
"""
|
"""
|
||||||
scripts = list(_scripts)
|
scripts = list(_scripts)
|
||||||
|
prefs = _bpy.context.user_preferences
|
||||||
|
|
||||||
# add user scripts dir
|
# add user scripts dir
|
||||||
if user_pref:
|
if user_pref:
|
||||||
user_script_path = _bpy.context.user_preferences.filepaths.script_directory
|
user_script_path = prefs.filepaths.script_directory
|
||||||
else:
|
else:
|
||||||
user_script_path = None
|
user_script_path = None
|
||||||
|
|
||||||
if all:
|
if all:
|
||||||
# all possible paths
|
# 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:
|
else:
|
||||||
# only paths blender uses
|
# only paths blender uses
|
||||||
base_paths = _bpy_script_paths()
|
base_paths = _bpy_script_paths()
|
||||||
@@ -426,7 +464,8 @@ def user_resource(type, path="", create=False):
|
|||||||
:type type: string
|
:type type: string
|
||||||
:arg subdir: Optional subdirectory.
|
:arg subdir: Optional subdirectory.
|
||||||
:type subdir: string
|
: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
|
:type create: boolean
|
||||||
:return: a path.
|
:return: a path.
|
||||||
:rtype: string
|
:rtype: string
|
||||||
@@ -477,7 +516,8 @@ def register_module(module, verbose=False):
|
|||||||
try:
|
try:
|
||||||
register_class(cls)
|
register_class(cls)
|
||||||
except:
|
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
|
import traceback
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
if verbose:
|
if verbose:
|
||||||
@@ -495,7 +535,8 @@ def unregister_module(module, verbose=False):
|
|||||||
try:
|
try:
|
||||||
unregister_class(cls)
|
unregister_class(cls)
|
||||||
except:
|
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
|
import traceback
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
if verbose:
|
if verbose:
|
||||||
|
@@ -16,7 +16,7 @@
|
|||||||
#
|
#
|
||||||
# ##### END GPL LICENSE BLOCK #####
|
# ##### END GPL LICENSE BLOCK #####
|
||||||
|
|
||||||
# <pep8 compliant>
|
# <pep8-80 compliant>
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Utility modules assosiated with the bpy module.
|
Utility modules assosiated with the bpy module.
|
||||||
@@ -28,4 +28,4 @@ __all__ = (
|
|||||||
"image_utils",
|
"image_utils",
|
||||||
"mesh_utils",
|
"mesh_utils",
|
||||||
"view3d_utils",
|
"view3d_utils",
|
||||||
)
|
)
|
||||||
|
@@ -16,11 +16,11 @@
|
|||||||
#
|
#
|
||||||
# ##### END GPL LICENSE BLOCK #####
|
# ##### END GPL LICENSE BLOCK #####
|
||||||
|
|
||||||
# <pep8 compliant>
|
# <pep8-80 compliant>
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
"load_image",
|
"load_image",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
# limited replacement for BPyImage.comprehensiveImageLoad
|
# limited replacement for BPyImage.comprehensiveImageLoad
|
||||||
@@ -33,8 +33,8 @@ def load_image(imagepath,
|
|||||||
verbose=False,
|
verbose=False,
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
Return an image from the file path with options to search multiple paths and
|
Return an image from the file path with options to search multiple paths
|
||||||
return a placeholder if its not found.
|
and return a placeholder if its not found.
|
||||||
|
|
||||||
:arg filepath: The image filename
|
:arg filepath: The image filename
|
||||||
If a path precedes it, this will be searched as well.
|
If a path precedes it, this will be searched as well.
|
||||||
@@ -51,9 +51,10 @@ def load_image(imagepath,
|
|||||||
:type recursive: bool
|
:type recursive: bool
|
||||||
:arg ncase_cmp: on non windows systems, find the correct case for the file.
|
:arg ncase_cmp: on non windows systems, find the correct case for the file.
|
||||||
:type ncase_cmp: bool
|
:type ncase_cmp: bool
|
||||||
:arg convert_callback: a function that takes an existing path and returns a new one.
|
:arg convert_callback: a function that takes an existing path and returns
|
||||||
Use this when loading image formats blender may not support, the CONVERT_CALLBACK
|
a new one. Use this when loading image formats blender may not support,
|
||||||
can take the path for a GIF (for example), convert it to a PNG and return the PNG's path.
|
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.
|
For formats blender can read, simply return the path that is given.
|
||||||
:type convert_callback: function
|
:type convert_callback: function
|
||||||
:return: an image or None
|
:return: an image or None
|
||||||
@@ -92,7 +93,9 @@ def load_image(imagepath,
|
|||||||
|
|
||||||
for filepath_test in variants:
|
for filepath_test in variants:
|
||||||
if ncase_cmp:
|
if ncase_cmp:
|
||||||
ncase_variants = filepath_test, bpy.path.resolve_ncase(filepath_test)
|
ncase_variants = (filepath_test,
|
||||||
|
bpy.path.resolve_ncase(filepath_test),
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
ncase_variants = (filepath_test, )
|
ncase_variants = (filepath_test, )
|
||||||
|
|
||||||
|
@@ -16,7 +16,7 @@
|
|||||||
#
|
#
|
||||||
# ##### END GPL LICENSE BLOCK #####
|
# ##### END GPL LICENSE BLOCK #####
|
||||||
|
|
||||||
# <pep8 compliant>
|
# <pep8-80 compliant>
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
"ExportHelper",
|
"ExportHelper",
|
||||||
@@ -31,15 +31,34 @@ __all__ = (
|
|||||||
"path_reference_copy",
|
"path_reference_copy",
|
||||||
"path_reference_mode",
|
"path_reference_mode",
|
||||||
"unique_name"
|
"unique_name"
|
||||||
)
|
)
|
||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
from bpy.props import StringProperty, BoolProperty, EnumProperty
|
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:
|
class ExportHelper:
|
||||||
filepath = StringProperty(name="File Path", description="Filepath used for exporting the file", maxlen=1024, default="", subtype='FILE_PATH')
|
filepath = StringProperty(
|
||||||
check_existing = BoolProperty(name="Check Existing", description="Check and warn on overwriting existing files", default=True, options={'HIDDEN'})
|
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
|
# subclasses can override with decorator
|
||||||
# True == use ext, False == no ext, None == do nothing.
|
# True == use ext, False == no ext, None == do nothing.
|
||||||
@@ -60,27 +79,39 @@ class ExportHelper:
|
|||||||
return {'RUNNING_MODAL'}
|
return {'RUNNING_MODAL'}
|
||||||
|
|
||||||
def check(self, context):
|
def check(self, context):
|
||||||
|
change_ext = False
|
||||||
|
change_axis = _check_axis_conversion(self)
|
||||||
|
|
||||||
check_extension = self.check_extension
|
check_extension = self.check_extension
|
||||||
|
|
||||||
if check_extension is None:
|
if check_extension is not None:
|
||||||
return False
|
filepath = bpy.path.ensure_ext(self.filepath,
|
||||||
|
self.filename_ext
|
||||||
filepath = bpy.path.ensure_ext(self.filepath, self.filename_ext if check_extension else "")
|
if check_extension
|
||||||
|
else "")
|
||||||
|
|
||||||
if filepath != self.filepath:
|
if filepath != self.filepath:
|
||||||
self.filepath = filepath
|
self.filepath = filepath
|
||||||
return True
|
change_ext = True
|
||||||
|
|
||||||
return False
|
return (change_ext or change_axis)
|
||||||
|
|
||||||
|
|
||||||
class ImportHelper:
|
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):
|
def invoke(self, context, event):
|
||||||
context.window_manager.fileselect_add(self)
|
context.window_manager.fileselect_add(self)
|
||||||
return {'RUNNING_MODAL'}
|
return {'RUNNING_MODAL'}
|
||||||
|
|
||||||
|
def check(self, context):
|
||||||
|
return _check_axis_conversion(self)
|
||||||
|
|
||||||
|
|
||||||
# Axis conversion function, not pretty LUT
|
# Axis conversion function, not pretty LUT
|
||||||
# use lookup tabes to convert between any axis
|
# 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...
|
# where all 4 values are or'd into a single value...
|
||||||
# (i1<<0 | i1<<3 | i1<<6 | i1<<9)
|
# (i1<<0 | i1<<3 | i1<<6 | i1<<9)
|
||||||
_axis_convert_lut = (
|
_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},
|
{0x8C8, 0x4D0, 0x2E0, 0xAE8, 0x701, 0x511, 0x119, 0xB29, 0x682, 0x88A,
|
||||||
{0xAC8, 0x8D0, 0x4E0, 0x2E8, 0x741, 0x951, 0x159, 0x369, 0x702, 0xB0A, 0x11A, 0x522, 0xA0B, 0x813, 0x423, 0x22B, 0x684, 0x894, 0x09C, 0x2AC, 0x645, 0xA4D, 0x05D, 0x465},
|
0x09A, 0x2A2, 0x80B, 0x413, 0x223, 0xA2B, 0x644, 0x454, 0x05C, 0xA6C,
|
||||||
{0x4C8, 0x2D0, 0xAE0, 0x8E8, 0x681, 0x291, 0x099, 0x8A9, 0x642, 0x44A, 0x05A, 0xA62, 0x40B, 0x213, 0xA23, 0x82B, 0x744, 0x354, 0x15C, 0x96C, 0x705, 0x50D, 0x11D, 0xB25},
|
0x745, 0x94D, 0x15D, 0x365},
|
||||||
{0x2C8, 0xAD0, 0x8E0, 0x4E8, 0x641, 0xA51, 0x059, 0x469, 0x742, 0x34A, 0x15A, 0x962, 0x20B, 0xA13, 0x823, 0x42B, 0x704, 0xB14, 0x11C, 0x52C, 0x685, 0x28D, 0x09D, 0x8A5},
|
{0xAC8, 0x8D0, 0x4E0, 0x2E8, 0x741, 0x951, 0x159, 0x369, 0x702, 0xB0A,
|
||||||
{0x708, 0xB10, 0x120, 0x528, 0x8C1, 0xAD1, 0x2D9, 0x4E9, 0x942, 0x74A, 0x35A, 0x162, 0x64B, 0xA53, 0x063, 0x46B, 0x804, 0xA14, 0x21C, 0x42C, 0x885, 0x68D, 0x29D, 0x0A5},
|
0x11A, 0x522, 0xA0B, 0x813, 0x423, 0x22B, 0x684, 0x894, 0x09C, 0x2AC,
|
||||||
{0xB08, 0x110, 0x520, 0x728, 0x941, 0x151, 0x359, 0x769, 0x802, 0xA0A, 0x21A, 0x422, 0xA4B, 0x053, 0x463, 0x66B, 0x884, 0x094, 0x29C, 0x6AC, 0x8C5, 0xACD, 0x2DD, 0x4E5},
|
0x645, 0xA4D, 0x05D, 0x465},
|
||||||
{0x508, 0x710, 0xB20, 0x128, 0x881, 0x691, 0x299, 0x0A9, 0x8C2, 0x4CA, 0x2DA, 0xAE2, 0x44B, 0x653, 0xA63, 0x06B, 0x944, 0x754, 0x35C, 0x16C, 0x805, 0x40D, 0x21D, 0xA25},
|
{0x4C8, 0x2D0, 0xAE0, 0x8E8, 0x681, 0x291, 0x099, 0x8A9, 0x642, 0x44A,
|
||||||
{0x108, 0x510, 0x720, 0xB28, 0x801, 0x411, 0x219, 0xA29, 0x882, 0x08A, 0x29A, 0x6A2, 0x04B, 0x453, 0x663, 0xA6B, 0x8C4, 0x4D4, 0x2DC, 0xAEC, 0x945, 0x14D, 0x35D, 0x765},
|
0x05A, 0xA62, 0x40B, 0x213, 0xA23, 0x82B, 0x744, 0x354, 0x15C, 0x96C,
|
||||||
{0x748, 0x350, 0x160, 0x968, 0xAC1, 0x2D1, 0x4D9, 0x8E9, 0xA42, 0x64A, 0x45A, 0x062, 0x68B, 0x293, 0x0A3, 0x8AB, 0xA04, 0x214, 0x41C, 0x82C, 0xB05, 0x70D, 0x51D, 0x125},
|
0x705, 0x50D, 0x11D, 0xB25},
|
||||||
{0x948, 0x750, 0x360, 0x168, 0xB01, 0x711, 0x519, 0x129, 0xAC2, 0x8CA, 0x4DA, 0x2E2, 0x88B, 0x693, 0x2A3, 0x0AB, 0xA44, 0x654, 0x45C, 0x06C, 0xA05, 0x80D, 0x41D, 0x225},
|
{0x2C8, 0xAD0, 0x8E0, 0x4E8, 0x641, 0xA51, 0x059, 0x469, 0x742, 0x34A,
|
||||||
{0x348, 0x150, 0x960, 0x768, 0xA41, 0x051, 0x459, 0x669, 0xA02, 0x20A, 0x41A, 0x822, 0x28B, 0x093, 0x8A3, 0x6AB, 0xB04, 0x114, 0x51C, 0x72C, 0xAC5, 0x2CD, 0x4DD, 0x8E5},
|
0x15A, 0x962, 0x20B, 0xA13, 0x823, 0x42B, 0x704, 0xB14, 0x11C, 0x52C,
|
||||||
{0x148, 0x950, 0x760, 0x368, 0xA01, 0x811, 0x419, 0x229, 0xB02, 0x10A, 0x51A, 0x722, 0x08B, 0x893, 0x6A3, 0x2AB, 0xAC4, 0x8D4, 0x4DC, 0x2EC, 0xA45, 0x04D, 0x45D, 0x665},
|
0x685, 0x28D, 0x09D, 0x8A5},
|
||||||
{0x688, 0x890, 0x0A0, 0x2A8, 0x4C1, 0x8D1, 0xAD9, 0x2E9, 0x502, 0x70A, 0xB1A, 0x122, 0x74B, 0x953, 0x163, 0x36B, 0x404, 0x814, 0xA1C, 0x22C, 0x445, 0x64D, 0xA5D, 0x065},
|
{0x708, 0xB10, 0x120, 0x528, 0x8C1, 0xAD1, 0x2D9, 0x4E9, 0x942, 0x74A,
|
||||||
{0x888, 0x090, 0x2A0, 0x6A8, 0x501, 0x111, 0xB19, 0x729, 0x402, 0x80A, 0xA1A, 0x222, 0x94B, 0x153, 0x363, 0x76B, 0x444, 0x054, 0xA5C, 0x66C, 0x4C5, 0x8CD, 0xADD, 0x2E5},
|
0x35A, 0x162, 0x64B, 0xA53, 0x063, 0x46B, 0x804, 0xA14, 0x21C, 0x42C,
|
||||||
{0x288, 0x690, 0x8A0, 0x0A8, 0x441, 0x651, 0xA59, 0x069, 0x4C2, 0x2CA, 0xADA, 0x8E2, 0x34B, 0x753, 0x963, 0x16B, 0x504, 0x714, 0xB1C, 0x12C, 0x405, 0x20D, 0xA1D, 0x825},
|
0x885, 0x68D, 0x29D, 0x0A5},
|
||||||
{0x088, 0x290, 0x6A0, 0x8A8, 0x401, 0x211, 0xA19, 0x829, 0x442, 0x04A, 0xA5A, 0x662, 0x14B, 0x353, 0x763, 0x96B, 0x4C4, 0x2D4, 0xADC, 0x8EC, 0x505, 0x10D, 0xB1D, 0x725},
|
{0xB08, 0x110, 0x520, 0x728, 0x941, 0x151, 0x359, 0x769, 0x802, 0xA0A,
|
||||||
{0x648, 0x450, 0x060, 0xA68, 0x2C1, 0x4D1, 0x8D9, 0xAE9, 0x282, 0x68A, 0x89A, 0x0A2, 0x70B, 0x513, 0x123, 0xB2B, 0x204, 0x414, 0x81C, 0xA2C, 0x345, 0x74D, 0x95D, 0x165},
|
0x21A, 0x422, 0xA4B, 0x053, 0x463, 0x66B, 0x884, 0x094, 0x29C, 0x6AC,
|
||||||
{0xA48, 0x650, 0x460, 0x068, 0x341, 0x751, 0x959, 0x169, 0x2C2, 0xACA, 0x8DA, 0x4E2, 0xB0B, 0x713, 0x523, 0x12B, 0x284, 0x694, 0x89C, 0x0AC, 0x205, 0xA0D, 0x81D, 0x425},
|
0x8C5, 0xACD, 0x2DD, 0x4E5},
|
||||||
{0x448, 0x050, 0xA60, 0x668, 0x281, 0x091, 0x899, 0x6A9, 0x202, 0x40A, 0x81A, 0xA22, 0x50B, 0x113, 0xB23, 0x72B, 0x344, 0x154, 0x95C, 0x76C, 0x2C5, 0x4CD, 0x8DD, 0xAE5},
|
{0x508, 0x710, 0xB20, 0x128, 0x881, 0x691, 0x299, 0x0A9, 0x8C2, 0x4CA,
|
||||||
{0x048, 0xA50, 0x660, 0x468, 0x201, 0xA11, 0x819, 0x429, 0x342, 0x14A, 0x95A, 0x762, 0x10B, 0xB13, 0x723, 0x52B, 0x2C4, 0xAD4, 0x8DC, 0x4EC, 0x285, 0x08D, 0x89D, 0x6A5},
|
0x2DA, 0xAE2, 0x44B, 0x653, 0xA63, 0x06B, 0x944, 0x754, 0x35C, 0x16C,
|
||||||
{0x808, 0xA10, 0x220, 0x428, 0x101, 0xB11, 0x719, 0x529, 0x142, 0x94A, 0x75A, 0x362, 0x8CB, 0xAD3, 0x2E3, 0x4EB, 0x044, 0xA54, 0x65C, 0x46C, 0x085, 0x88D, 0x69D, 0x2A5},
|
0x805, 0x40D, 0x21D, 0xA25},
|
||||||
{0xA08, 0x210, 0x420, 0x828, 0x141, 0x351, 0x759, 0x969, 0x042, 0xA4A, 0x65A, 0x462, 0xACB, 0x2D3, 0x4E3, 0x8EB, 0x084, 0x294, 0x69C, 0x8AC, 0x105, 0xB0D, 0x71D, 0x525},
|
{0x108, 0x510, 0x720, 0xB28, 0x801, 0x411, 0x219, 0xA29, 0x882, 0x08A,
|
||||||
{0x408, 0x810, 0xA20, 0x228, 0x081, 0x891, 0x699, 0x2A9, 0x102, 0x50A, 0x71A, 0xB22, 0x4CB, 0x8D3, 0xAE3, 0x2EB, 0x144, 0x954, 0x75C, 0x36C, 0x045, 0x44D, 0x65D, 0xA65},
|
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}
|
_axis_convert_num = {'X': 0, 'Y': 1, 'Z': 2, '-X': 3, '-Y': 4, '-Z': 5}
|
||||||
@@ -159,7 +236,12 @@ def axis_conversion(from_forward='Y', from_up='Z', to_forward='Y', to_up='Z'):
|
|||||||
raise Exception("invalid axis arguments passed, "
|
raise Exception("invalid axis arguments passed, "
|
||||||
"can't use up/forward on the same axis.")
|
"can't use up/forward on the same axis.")
|
||||||
|
|
||||||
value = reduce(int.__or__, (_axis_convert_num[a] << (i * 3) for i, a in enumerate((from_forward, from_up, to_forward, to_up))))
|
value = reduce(int.__or__, (_axis_convert_num[a] << (i * 3)
|
||||||
|
for i, a in enumerate((from_forward,
|
||||||
|
from_up,
|
||||||
|
to_forward,
|
||||||
|
to_up,
|
||||||
|
))))
|
||||||
|
|
||||||
for i, axis_lut in enumerate(_axis_convert_lut):
|
for i, axis_lut in enumerate(_axis_convert_lut):
|
||||||
if value in axis_lut:
|
if value in axis_lut:
|
||||||
@@ -174,9 +256,9 @@ def axis_conversion_ensure(operator, forward_attr, up_attr):
|
|||||||
|
|
||||||
:arg operator: the operator to access axis attributes from.
|
:arg operator: the operator to access axis attributes from.
|
||||||
:type operator: :class:`Operator`
|
:type operator: :class:`Operator`
|
||||||
:arg forward_attr:
|
:arg forward_attr: attribute storing the forward axis
|
||||||
:type forward_attr: string
|
:type forward_attr: string
|
||||||
:arg up_attr: the directory the *filepath* will be referenced from (normally the export path).
|
:arg up_attr: attribute storing the up axis
|
||||||
:type up_attr: string
|
:type up_attr: string
|
||||||
:return: True if the value was modified.
|
:return: True if the value was modified.
|
||||||
:rtype: boolean
|
:rtype: boolean
|
||||||
@@ -201,7 +283,8 @@ def axis_conversion_ensure(operator, forward_attr, up_attr):
|
|||||||
return False
|
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):
|
def create_derived_objects(scene, ob):
|
||||||
if ob.parent and ob.parent.dupli_type in {'VERTS', 'FACES'}:
|
if ob.parent and ob.parent.dupli_type in {'VERTS', 'FACES'}:
|
||||||
return False, None
|
return False, None
|
||||||
@@ -249,31 +332,45 @@ path_reference_mode = EnumProperty(
|
|||||||
description="Method used to reference paths",
|
description="Method used to reference paths",
|
||||||
items=(('AUTO', "Auto", "Use Relative paths with subdirectories only"),
|
items=(('AUTO', "Auto", "Use Relative paths with subdirectories only"),
|
||||||
('ABSOLUTE', "Absolute", "Always write absolute paths"),
|
('ABSOLUTE', "Absolute", "Always write absolute paths"),
|
||||||
('RELATIVE', "Relative", "Always write relative patsh (where possible)"),
|
('RELATIVE', "Relative", "Always write relative patsh "
|
||||||
('MATCH', "Match", "Match Absolute/Relative setting with input path"),
|
"(where possible)"),
|
||||||
|
('MATCH', "Match", "Match Absolute/Relative "
|
||||||
|
"setting with input path"),
|
||||||
('STRIP', "Strip Path", "Filename only"),
|
('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'
|
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
|
Return a filepath relative to a destination directory, for use with
|
||||||
exporters.
|
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
|
: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
|
: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
|
: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
|
:type mode: string
|
||||||
:arg copy_subdir: the subdirectory of *base_dst* to use when mode='COPY'.
|
:arg copy_subdir: the subdirectory of *base_dst* to use when mode='COPY'.
|
||||||
:type copy_subdir: string
|
: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
|
:type copy_set: set
|
||||||
:return: the new filepath.
|
:return: the new filepath.
|
||||||
:rtype: string
|
:rtype: string
|
||||||
@@ -282,12 +379,14 @@ def path_reference(filepath, base_src, base_dst, mode='AUTO', copy_subdir="", co
|
|||||||
is_relative = filepath.startswith("//")
|
is_relative = filepath.startswith("//")
|
||||||
filepath_abs = os.path.normpath(bpy.path.abspath(filepath, base_src))
|
filepath_abs = os.path.normpath(bpy.path.abspath(filepath, base_src))
|
||||||
|
|
||||||
if mode in ('ABSOLUTE', 'RELATIVE', 'STRIP'):
|
if mode in {'ABSOLUTE', 'RELATIVE', 'STRIP'}:
|
||||||
pass
|
pass
|
||||||
elif mode == 'MATCH':
|
elif mode == 'MATCH':
|
||||||
mode = 'RELATIVE' if is_relative else 'ABSOLUTE'
|
mode = 'RELATIVE' if is_relative else 'ABSOLUTE'
|
||||||
elif mode == 'AUTO':
|
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':
|
elif mode == 'COPY':
|
||||||
if copy_subdir:
|
if copy_subdir:
|
||||||
subdir_abs = os.path.join(os.path.normpath(base_dst), copy_subdir)
|
subdir_abs = os.path.join(os.path.normpath(base_dst), copy_subdir)
|
||||||
@@ -362,7 +461,8 @@ def unique_name(key, name, name_dict, name_max=-1, clean_func=None):
|
|||||||
if name_new is None:
|
if name_new is None:
|
||||||
count = 1
|
count = 1
|
||||||
name_dict_values = name_dict.values()
|
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:
|
if name_max == -1:
|
||||||
while name_new in name_dict_values:
|
while name_new in name_dict_values:
|
||||||
@@ -372,7 +472,10 @@ def unique_name(key, name, name_dict, name_max=-1, clean_func=None):
|
|||||||
name_new = name_new[:name_max]
|
name_new = name_new[:name_max]
|
||||||
while name_new in name_dict_values:
|
while name_new in name_dict_values:
|
||||||
count_str = "%03d" % count
|
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
|
count += 1
|
||||||
|
|
||||||
name_dict[key] = name_new
|
name_dict[key] = name_new
|
||||||
|
@@ -26,7 +26,7 @@ __all__ = (
|
|||||||
"edge_loops_from_edges",
|
"edge_loops_from_edges",
|
||||||
"ngon_tesselate",
|
"ngon_tesselate",
|
||||||
"face_random_points",
|
"face_random_points",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def mesh_linked_faces(mesh):
|
def mesh_linked_faces(mesh):
|
||||||
@@ -170,8 +170,8 @@ def edge_loops_from_faces(mesh, faces=None, seams=()):
|
|||||||
# from knowing the last 2, look for th next.
|
# from knowing the last 2, look for th next.
|
||||||
ed_adj = edges[context_loop[-1]]
|
ed_adj = edges[context_loop[-1]]
|
||||||
if len(ed_adj) != 2:
|
if len(ed_adj) != 2:
|
||||||
|
# the original edge had 2 other edges
|
||||||
if other_dir and flipped == False: # the original edge had 2 other edges
|
if other_dir and flipped == False:
|
||||||
flipped = True # only flip the list once
|
flipped = True # only flip the list once
|
||||||
context_loop.reverse()
|
context_loop.reverse()
|
||||||
ed_adj[:] = []
|
ed_adj[:] = []
|
||||||
@@ -259,13 +259,15 @@ def edge_loops_from_edges(mesh, edges=None):
|
|||||||
|
|
||||||
def ngon_tesselate(from_data, indices, fix_loops=True):
|
def ngon_tesselate(from_data, indices, fix_loops=True):
|
||||||
'''
|
'''
|
||||||
Takes a polyline of indices (fgon)
|
Takes a polyline of indices (fgon) and returns a list of face
|
||||||
and returns a list of face indicie lists.
|
indicie lists. Designed to be used for importers that need indices for an
|
||||||
Designed to be used for importers that need indices for an fgon to create from existing verts.
|
fgon to create from existing verts.
|
||||||
|
|
||||||
from_data: either a mesh, or a list/tuple of vectors.
|
from_data: either a mesh, or a list/tuple of vectors.
|
||||||
indices: a list of indices to use this list is the ordered closed polyline to fill, and can be a subset of the data given.
|
indices: a list of indices to use this list is the ordered closed polyline
|
||||||
fix_loops: If this is enabled polylines that use loops to make multiple polylines are delt with correctly.
|
to fill, and can be a subset of the data given.
|
||||||
|
fix_loops: If this is enabled polylines that use loops to make multiple
|
||||||
|
polylines are delt with correctly.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
from mathutils.geometry import tesselate_polygon
|
from mathutils.geometry import tesselate_polygon
|
||||||
@@ -276,7 +278,8 @@ def ngon_tesselate(from_data, indices, fix_loops=True):
|
|||||||
return []
|
return []
|
||||||
|
|
||||||
def mlen(co):
|
def mlen(co):
|
||||||
return abs(co[0]) + abs(co[1]) + abs(co[2]) # manhatten length of a vector, faster then length
|
# manhatten length of a vector, faster then length
|
||||||
|
return abs(co[0]) + abs(co[1]) + abs(co[2])
|
||||||
|
|
||||||
def vert_treplet(v, i):
|
def vert_treplet(v, i):
|
||||||
return v, vector_to_tuple(v, 6), i, mlen(v)
|
return v, vector_to_tuple(v, 6), i, mlen(v)
|
||||||
@@ -291,12 +294,13 @@ def ngon_tesselate(from_data, indices, fix_loops=True):
|
|||||||
'''
|
'''
|
||||||
Normal single concave loop filling
|
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)]
|
verts = [Vector(from_data[i]) for ii, i in enumerate(indices)]
|
||||||
else:
|
else:
|
||||||
verts = [from_data.vertices[i].co for ii, i in enumerate(indices)]
|
verts = [from_data.vertices[i].co for ii, i in enumerate(indices)]
|
||||||
|
|
||||||
for i in range(len(verts) - 1, 0, -1): # same as reversed(xrange(1, len(verts))):
|
# same as reversed(range(1, len(verts))):
|
||||||
|
for i in range(len(verts) - 1, 0, -1):
|
||||||
if verts[i][1] == verts[i - 1][0]:
|
if verts[i][1] == verts[i - 1][0]:
|
||||||
verts.pop(i - 1)
|
verts.pop(i - 1)
|
||||||
|
|
||||||
@@ -304,14 +308,16 @@ def ngon_tesselate(from_data, indices, fix_loops=True):
|
|||||||
|
|
||||||
else:
|
else:
|
||||||
'''
|
'''
|
||||||
Seperate this loop into multiple loops be finding edges that are used twice
|
Seperate this loop into multiple loops be finding edges that are
|
||||||
This is used by lightwave LWO files a lot
|
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)]
|
verts = [vert_treplet(Vector(from_data[i]), ii)
|
||||||
|
for ii, i in enumerate(indices)]
|
||||||
else:
|
else:
|
||||||
verts = [vert_treplet(from_data.vertices[i].co, ii) for ii, i in enumerate(indices)]
|
verts = [vert_treplet(from_data.vertices[i].co, ii)
|
||||||
|
for ii, i in enumerate(indices)]
|
||||||
|
|
||||||
edges = [(i, i - 1) for i in range(len(verts))]
|
edges = [(i, i - 1) for i in range(len(verts))]
|
||||||
if edges:
|
if edges:
|
||||||
|
@@ -16,12 +16,12 @@
|
|||||||
#
|
#
|
||||||
# ##### END GPL LICENSE BLOCK #####
|
# ##### END GPL LICENSE BLOCK #####
|
||||||
|
|
||||||
# <pep8 compliant>
|
# <pep8-80 compliant>
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
"add_object_align_init",
|
"add_object_align_init",
|
||||||
"object_data_add",
|
"object_data_add",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
@@ -39,42 +39,49 @@ def add_object_align_init(context, operator):
|
|||||||
:return: the matrix from the context and settings.
|
:return: the matrix from the context and settings.
|
||||||
:rtype: :class:`Matrix`
|
:rtype: :class:`Matrix`
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
from mathutils import Matrix, Vector, Euler
|
||||||
|
properties = operator.properties if operator is not None else None
|
||||||
|
|
||||||
space_data = context.space_data
|
space_data = context.space_data
|
||||||
if space_data.type != 'VIEW_3D':
|
if space_data.type != 'VIEW_3D':
|
||||||
space_data = None
|
space_data = None
|
||||||
|
|
||||||
# location
|
# location
|
||||||
if operator and operator.properties.is_property_set("location"):
|
if operator and properties.is_property_set("location"):
|
||||||
location = mathutils.Matrix.Translation(mathutils.Vector(operator.properties.location))
|
location = Matrix.Translation(Vector(properties.location))
|
||||||
else:
|
else:
|
||||||
if space_data: # local view cursor is detected below
|
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:
|
else:
|
||||||
location = mathutils.Matrix.Translation(context.scene.cursor_location)
|
location = Matrix.Translation(context.scene.cursor_location)
|
||||||
|
|
||||||
if operator:
|
if operator:
|
||||||
operator.properties.location = location.to_translation()
|
properties.location = location.to_translation()
|
||||||
|
|
||||||
# rotation
|
# rotation
|
||||||
view_align = (context.user_preferences.edit.object_align == 'VIEW')
|
view_align = (context.user_preferences.edit.object_align == 'VIEW')
|
||||||
view_align_force = False
|
view_align_force = False
|
||||||
if operator:
|
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
|
view_align = view_align_force = operator.view_align
|
||||||
else:
|
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:
|
if operator and (properties.is_property_set("rotation") and
|
||||||
rotation = mathutils.Euler(operator.properties.rotation).to_matrix().to_4x4()
|
not view_align_force):
|
||||||
|
|
||||||
|
rotation = Euler(properties.rotation).to_matrix().to_4x4()
|
||||||
else:
|
else:
|
||||||
if view_align and space_data:
|
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:
|
else:
|
||||||
rotation = mathutils.Matrix()
|
rotation = mathutils.Matrix()
|
||||||
|
|
||||||
# set the operator properties
|
# set the operator properties
|
||||||
if operator:
|
if operator:
|
||||||
operator.properties.rotation = rotation.to_euler()
|
properties.rotation = rotation.to_euler()
|
||||||
|
|
||||||
return location * rotation
|
return location * rotation
|
||||||
|
|
||||||
@@ -114,14 +121,18 @@ def object_data_add(context, obdata, operator=None):
|
|||||||
# XXX
|
# XXX
|
||||||
# caused because entering editmodedoes not add a empty undo slot!
|
# caused because entering editmodedoes not add a empty undo slot!
|
||||||
if context.user_preferences.edit.use_enter_edit_mode:
|
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)
|
_obdata = bpy.data.meshes.new(obdata.name)
|
||||||
obj_act = bpy.data.objects.new(_obdata.name, _obdata)
|
obj_act = bpy.data.objects.new(_obdata.name, _obdata)
|
||||||
obj_act.matrix_world = obj_new.matrix_world
|
obj_act.matrix_world = obj_new.matrix_world
|
||||||
scene.objects.link(obj_act)
|
scene.objects.link(obj_act)
|
||||||
scene.objects.active = obj_act
|
scene.objects.active = obj_act
|
||||||
bpy.ops.object.mode_set(mode='EDIT')
|
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
|
# XXX
|
||||||
|
|
||||||
if obj_act and obj_act.mode == 'EDIT' and obj_act.type == obj_new.type:
|
if obj_act and obj_act.mode == 'EDIT' and obj_act.type == obj_new.type:
|
||||||
|
@@ -16,13 +16,13 @@
|
|||||||
#
|
#
|
||||||
# ##### END GPL LICENSE BLOCK #####
|
# ##### END GPL LICENSE BLOCK #####
|
||||||
|
|
||||||
# <pep8 compliant>
|
# <pep8-80 compliant>
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
"region_2d_to_vector_3d",
|
"region_2d_to_vector_3d",
|
||||||
"region_2d_to_location_3d",
|
"region_2d_to_location_3d",
|
||||||
"location_3d_to_region_2d",
|
"location_3d_to_region_2d",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def region_2d_to_vector_3d(region, rv3d, coord):
|
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_start = rv3d.view_matrix.inverted()[3].to_3d()
|
||||||
origin_end = origin_start + coord_vec
|
origin_end = origin_start + coord_vec
|
||||||
view_vec = rv3d.view_matrix.inverted()[2]
|
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:
|
else:
|
||||||
dx = (2.0 * coord[0] / region.width) - 1.0
|
dx = (2.0 * coord[0] / region.width) - 1.0
|
||||||
dy = (2.0 * coord[1] / region.height) - 1.0
|
dy = (2.0 * coord[1] / region.height) - 1.0
|
||||||
persinv = persmat.inverted()
|
persinv = persmat.inverted()
|
||||||
viewinv = rv3d.view_matrix.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
|
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):
|
def location_3d_to_region_2d(region, rv3d, coord):
|
||||||
|
@@ -120,7 +120,7 @@ def fromxml(data):
|
|||||||
py_item = (xml_node.tagName, _fromxml_kwargs(xml_node), [])
|
py_item = (xml_node.tagName, _fromxml_kwargs(xml_node), [])
|
||||||
#_fromxml_iter(py_item, xml_node.childNodes)
|
#_fromxml_iter(py_item, xml_node.childNodes)
|
||||||
for xml_node_child in 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))
|
py_item[CHILDREN].append(_fromxml(xml_node_child))
|
||||||
return py_item
|
return py_item
|
||||||
|
|
||||||
|
@@ -40,13 +40,13 @@ def _parse_rna(prop, value):
|
|||||||
elif prop.type == 'INT':
|
elif prop.type == 'INT':
|
||||||
value = int(value)
|
value = int(value)
|
||||||
elif prop.type == 'BOOLEAN':
|
elif prop.type == 'BOOLEAN':
|
||||||
if value in (True, False):
|
if value in {True, False}:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
if value not in ("True", "False"):
|
if value not in {"True", "False"}:
|
||||||
raise Exception("invalid bool value: %s" % value)
|
raise Exception("invalid bool value: %s" % value)
|
||||||
value = bool(value == "True")
|
value = bool(value == "True")
|
||||||
elif prop.type in ('STRING', 'ENUM'):
|
elif prop.type in {'STRING', 'ENUM'}:
|
||||||
pass
|
pass
|
||||||
elif prop.type == 'POINTER':
|
elif prop.type == 'POINTER':
|
||||||
value = eval("_bpy." + value)
|
value = eval("_bpy." + value)
|
||||||
|
@@ -16,14 +16,14 @@
|
|||||||
#
|
#
|
||||||
# ##### END GPL LICENSE BLOCK #####
|
# ##### END GPL LICENSE BLOCK #####
|
||||||
|
|
||||||
# <pep8 compliant>
|
# <pep8-80 compliant>
|
||||||
|
|
||||||
# This file defines a set of methods that are useful for various
|
# This file defines a set of methods that are useful for various
|
||||||
# Relative Keying Set (RKS) related operations, such as: callbacks
|
# Relative Keying Set (RKS) related operations, such as: callbacks
|
||||||
# for polling, iterator callbacks, and also generate callbacks.
|
# for polling, iterator callbacks, and also generate callbacks.
|
||||||
# All of these can be used in conjunction with the others.
|
# All of these can be used in conjunction with the others.
|
||||||
|
|
||||||
__all__ = [
|
__all__ = (
|
||||||
"path_add_property",
|
"path_add_property",
|
||||||
"RKS_POLL_selected_objects",
|
"RKS_POLL_selected_objects",
|
||||||
"RKS_POLL_selected_bones",
|
"RKS_POLL_selected_bones",
|
||||||
@@ -33,7 +33,7 @@ __all__ = [
|
|||||||
"RKS_GEN_location",
|
"RKS_GEN_location",
|
||||||
"RKS_GEN_rotation",
|
"RKS_GEN_rotation",
|
||||||
"RKS_GEN_scaling",
|
"RKS_GEN_scaling",
|
||||||
]
|
)
|
||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
|
|
||||||
@@ -75,7 +75,8 @@ def RKS_POLL_selected_bones(ksi, context):
|
|||||||
|
|
||||||
# selected bones or objects
|
# selected bones or objects
|
||||||
def RKS_POLL_selected_items(ksi, context):
|
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
|
# Iterator Callbacks
|
||||||
|
@@ -148,7 +148,7 @@ class InfoStructRNA:
|
|||||||
import types
|
import types
|
||||||
functions = []
|
functions = []
|
||||||
for identifier, attr in self._get_py_visible_attrs():
|
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))
|
functions.append((identifier, attr))
|
||||||
return functions
|
return functions
|
||||||
|
|
||||||
@@ -156,7 +156,7 @@ class InfoStructRNA:
|
|||||||
import types
|
import types
|
||||||
functions = []
|
functions = []
|
||||||
for identifier, attr in self._get_py_visible_attrs():
|
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))
|
functions.append((identifier, attr))
|
||||||
return functions
|
return functions
|
||||||
|
|
||||||
@@ -260,7 +260,7 @@ class InfoPropertyRNA:
|
|||||||
if self.array_length:
|
if self.array_length:
|
||||||
type_str += " array of %d items" % (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))
|
type_str += " in [%s, %s]" % (range_str(self.min), range_str(self.max))
|
||||||
elif self.type == "enum":
|
elif self.type == "enum":
|
||||||
if self.is_enum_flag:
|
if self.is_enum_flag:
|
||||||
@@ -595,7 +595,7 @@ def BuildRNAInfo():
|
|||||||
for prop in rna_info.properties:
|
for prop in rna_info.properties:
|
||||||
# ERROR CHECK
|
# ERROR CHECK
|
||||||
default = prop.default
|
default = prop.default
|
||||||
if type(default) in (float, int):
|
if type(default) in {float, int}:
|
||||||
if default < prop.min or default > prop.max:
|
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))
|
print("\t %s.%s, %s not in [%s - %s]" % (rna_info.identifier, prop.identifier, default, prop.min, prop.max))
|
||||||
|
|
||||||
|
@@ -1,8 +1,7 @@
|
|||||||
import bpy
|
import bpy
|
||||||
is_ntsc = (bpy.context.scene.render.fps != 25)
|
is_ntsc = (bpy.context.scene.render.fps != 25)
|
||||||
|
|
||||||
bpy.context.scene.render.ffmpeg_format = "AVI"
|
bpy.context.scene.render.ffmpeg_format = "XVID"
|
||||||
bpy.context.scene.render.ffmpeg_codec = "XVID"
|
|
||||||
|
|
||||||
if is_ntsc:
|
if is_ntsc:
|
||||||
bpy.context.scene.render.ffmpeg_gopsize = 18
|
bpy.context.scene.render.ffmpeg_gopsize = 18
|
||||||
|
@@ -61,13 +61,19 @@ class EditExternally(bpy.types.Operator):
|
|||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
import os
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
filepath = os.path.normpath(bpy.path.abspath(self.filepath))
|
|
||||||
|
filepath = self.filepath
|
||||||
|
|
||||||
|
if not filepath:
|
||||||
|
self.report({'ERROR'}, "Image path not set")
|
||||||
|
return {'CANCELLED'}
|
||||||
|
|
||||||
|
filepath = os.path.normpath(bpy.path.abspath(filepath))
|
||||||
|
|
||||||
if not os.path.exists(filepath):
|
if not os.path.exists(filepath):
|
||||||
self.report({'ERROR'},
|
self.report({'ERROR'},
|
||||||
"Image path %r not found, image may be packed or "
|
"Image path %r not found, image may be packed or "
|
||||||
"unsaved." % filepath)
|
"unsaved." % filepath)
|
||||||
|
|
||||||
return {'CANCELLED'}
|
return {'CANCELLED'}
|
||||||
|
|
||||||
cmd = self._editor_guess(context) + [filepath]
|
cmd = self._editor_guess(context) + [filepath]
|
||||||
|
@@ -22,6 +22,7 @@ import bpy
|
|||||||
from mathutils import Vector
|
from mathutils import Vector
|
||||||
from blf import gettext as _
|
from blf import gettext as _
|
||||||
|
|
||||||
|
|
||||||
def GlobalBB_LQ(bb_world):
|
def GlobalBB_LQ(bb_world):
|
||||||
|
|
||||||
# Initialize the variables with the 8th vertex
|
# Initialize the variables with the 8th vertex
|
||||||
@@ -34,7 +35,7 @@ def GlobalBB_LQ(bb_world):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Test against the other 7 verts
|
# Test against the other 7 verts
|
||||||
for i in range (7):
|
for i in range(7):
|
||||||
|
|
||||||
# X Range
|
# X Range
|
||||||
val = bb_world[i][0]
|
val = bb_world[i][0]
|
||||||
@@ -62,6 +63,7 @@ def GlobalBB_LQ(bb_world):
|
|||||||
|
|
||||||
return (Vector((left, front, up)), Vector((right, back, down)))
|
return (Vector((left, front, up)), Vector((right, back, down)))
|
||||||
|
|
||||||
|
|
||||||
def GlobalBB_HQ(obj):
|
def GlobalBB_HQ(obj):
|
||||||
|
|
||||||
matrix_world = obj.matrix_world.copy()
|
matrix_world = obj.matrix_world.copy()
|
||||||
@@ -81,7 +83,7 @@ def GlobalBB_HQ(obj):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Test against all other verts
|
# Test against all other verts
|
||||||
for i in range (len(verts)-1):
|
for i in range(len(verts) - 1):
|
||||||
|
|
||||||
vco = matrix_world * verts[i].co
|
vco = matrix_world * verts[i].co
|
||||||
|
|
||||||
|
@@ -520,7 +520,7 @@ def unwrap(operator, context, **kwargs):
|
|||||||
if obj and obj.type == 'MESH':
|
if obj and obj.type == 'MESH':
|
||||||
meshes = [obj.data]
|
meshes = [obj.data]
|
||||||
else:
|
else:
|
||||||
meshes = {me.name: me for obj in context.selected_objects if obj.type == 'MESH' for me in (obj.data,) if not me.library if len(me.faces)}.values()
|
meshes = list({me for obj in context.selected_objects if obj.type == 'MESH' for me in (obj.data,) if me.faces and me.library is None})
|
||||||
|
|
||||||
if not meshes:
|
if not meshes:
|
||||||
operator.report({'ERROR'}, "No mesh object.")
|
operator.report({'ERROR'}, "No mesh object.")
|
||||||
|
@@ -587,7 +587,7 @@ class WM_OT_context_modal_mouse(bpy.types.Operator):
|
|||||||
self._values_clear()
|
self._values_clear()
|
||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
|
|
||||||
elif event_type in ('RIGHTMOUSE', 'ESC'):
|
elif event_type in {'RIGHTMOUSE', 'ESC'}:
|
||||||
self._values_restore()
|
self._values_restore()
|
||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
|
|
||||||
@@ -841,7 +841,7 @@ class WM_OT_properties_edit(bpy.types.Operator):
|
|||||||
|
|
||||||
prop_ui = rna_idprop_ui_prop_get(item, prop)
|
prop_ui = rna_idprop_ui_prop_get(item, prop)
|
||||||
|
|
||||||
if prop_type in (float, int):
|
if prop_type in {float, int}:
|
||||||
|
|
||||||
prop_ui['soft_min'] = prop_ui['min'] = prop_type(self.min)
|
prop_ui['soft_min'] = prop_ui['min'] = prop_type(self.min)
|
||||||
prop_ui['soft_max'] = prop_ui['max'] = prop_type(self.max)
|
prop_ui['soft_max'] = prop_ui['max'] = prop_type(self.max)
|
||||||
|
@@ -361,7 +361,7 @@ class DATA_PT_paragraph(CurveButtonsPanel, bpy.types.Panel):
|
|||||||
col.prop(text, "offset_y", text="Y")
|
col.prop(text, "offset_y", text="Y")
|
||||||
|
|
||||||
|
|
||||||
class DATA_PT_textboxes(CurveButtonsPanel, bpy.types.Panel):
|
class DATA_PT_text_boxes(CurveButtonsPanel, bpy.types.Panel):
|
||||||
bl_label = _("Text Boxes")
|
bl_label = _("Text Boxes")
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
@@ -41,11 +41,9 @@ class DATA_PT_empty(DataButtonsPanel, bpy.types.Panel):
|
|||||||
layout.prop(ob, "empty_draw_type", text=_("Display"))
|
layout.prop(ob, "empty_draw_type", text=_("Display"))
|
||||||
|
|
||||||
if ob.empty_draw_type == 'IMAGE':
|
if ob.empty_draw_type == 'IMAGE':
|
||||||
# layout.template_image(ob, "data", None)
|
|
||||||
layout.template_ID(ob, "data", open="image.open", unlink="image.unlink")
|
layout.template_ID(ob, "data", open="image.open", unlink="image.unlink")
|
||||||
|
|
||||||
row = layout.row(align=True)
|
layout.prop(ob, "color", text=_("Transparency"), index=3, slider=True)
|
||||||
row.prop(ob, "color", text=_("Transparency"), index=3, slider=True)
|
|
||||||
row = layout.row(align=True)
|
row = layout.row(align=True)
|
||||||
row.prop(ob, "empty_image_offset", text=_("Offset X"), index=0)
|
row.prop(ob, "empty_image_offset", text=_("Offset X"), index=0)
|
||||||
row.prop(ob, "empty_image_offset", text=_("Offset Y"), index=1)
|
row.prop(ob, "empty_image_offset", text=_("Offset Y"), index=1)
|
||||||
|
@@ -247,15 +247,17 @@ class MATERIAL_PT_diffuse(MaterialButtonsPanel, bpy.types.Panel):
|
|||||||
row.prop(mat, "diffuse_fresnel_factor", text=_("Factor"))
|
row.prop(mat, "diffuse_fresnel_factor", text=_("Factor"))
|
||||||
|
|
||||||
if mat.use_diffuse_ramp:
|
if mat.use_diffuse_ramp:
|
||||||
layout.separator()
|
col = layout.column()
|
||||||
layout.template_color_ramp(mat, "diffuse_ramp", expand=True)
|
col.active = (not mat.use_shadeless)
|
||||||
layout.separator()
|
col.separator()
|
||||||
|
col.template_color_ramp(mat, "diffuse_ramp", expand=True)
|
||||||
|
col.separator()
|
||||||
|
|
||||||
row = layout.row()
|
row = col.row()
|
||||||
row.prop(mat, "diffuse_ramp_input", text=_("Input"))
|
row.prop(mat, "diffuse_ramp_input", text=_("Input"))
|
||||||
row.prop(mat, "diffuse_ramp_blend", text=_("Blend"))
|
row.prop(mat, "diffuse_ramp_blend", text=_("Blend"))
|
||||||
|
|
||||||
layout.prop(mat, "diffuse_ramp_factor", text=_("Factor"))
|
col.prop(mat, "diffuse_ramp_factor", text=_("Factor"))
|
||||||
|
|
||||||
|
|
||||||
class MATERIAL_PT_specular(MaterialButtonsPanel, bpy.types.Panel):
|
class MATERIAL_PT_specular(MaterialButtonsPanel, bpy.types.Panel):
|
||||||
|
@@ -463,7 +463,7 @@ class PARTICLE_PT_physics(ParticleButtonsPanel, bpy.types.Panel):
|
|||||||
col.prop(part, "mass")
|
col.prop(part, "mass")
|
||||||
col.prop(part, "use_multiply_size_mass", text=_("Multiply mass with size"))
|
col.prop(part, "use_multiply_size_mass", text=_("Multiply mass with size"))
|
||||||
|
|
||||||
if part.physics_type in ('NEWTON', 'FLUID'):
|
if part.physics_type in {'NEWTON', 'FLUID'}:
|
||||||
split = layout.split()
|
split = layout.split()
|
||||||
|
|
||||||
col = split.column()
|
col = split.column()
|
||||||
@@ -922,7 +922,7 @@ class PARTICLE_PT_render(ParticleButtonsPanel, bpy.types.Panel):
|
|||||||
col = row.column()
|
col = row.column()
|
||||||
col.label(text="")
|
col.label(text="")
|
||||||
|
|
||||||
if part.render_type in ('OBJECT', 'GROUP') and not part.use_advanced_hair:
|
if part.render_type in {'OBJECT', 'GROUP'} and not part.use_advanced_hair:
|
||||||
row = layout.row(align=True)
|
row = layout.row(align=True)
|
||||||
row.prop(part, "particle_size")
|
row.prop(part, "particle_size")
|
||||||
row.prop(part, "size_random", slider=True)
|
row.prop(part, "size_random", slider=True)
|
||||||
|
@@ -353,7 +353,7 @@ class INFO_MT_help(bpy.types.Menu):
|
|||||||
layout = self.layout
|
layout = self.layout
|
||||||
|
|
||||||
layout.operator("wm.url_open", text=_("Manual"), icon='HELP').url = 'http://wiki.blender.org/index.php/Doc:Manual'
|
layout.operator("wm.url_open", text=_("Manual"), icon='HELP').url = 'http://wiki.blender.org/index.php/Doc:Manual'
|
||||||
layout.operator("wm.url_open", text=_("Release Log"), icon='URL').url = 'http://www.blender.org/development/release-logs/blender-257/'
|
layout.operator("wm.url_open", text=_("Release Log"), icon='URL').url = 'http://www.blender.org/development/release-logs/blender-259/'
|
||||||
|
|
||||||
layout.separator()
|
layout.separator()
|
||||||
|
|
||||||
|
@@ -755,6 +755,31 @@ class USERPREF_PT_file(bpy.types.Panel):
|
|||||||
from bl_ui.space_userpref_keymap import InputKeyMapPanel
|
from bl_ui.space_userpref_keymap import InputKeyMapPanel
|
||||||
|
|
||||||
|
|
||||||
|
class USERPREF_MT_ndof_settings(bpy.types.Menu):
|
||||||
|
# accessed from the window keybindings in C (only)
|
||||||
|
bl_label = _("3D Mouse Settings")
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
layout = self.layout
|
||||||
|
input_prefs = context.user_preferences.inputs
|
||||||
|
|
||||||
|
layout.separator()
|
||||||
|
layout.prop(input_prefs, "ndof_sensitivity")
|
||||||
|
|
||||||
|
if context.space_data.type == 'VIEW_3D':
|
||||||
|
layout.separator()
|
||||||
|
layout.prop(input_prefs, "ndof_show_guide")
|
||||||
|
|
||||||
|
layout.separator()
|
||||||
|
layout.label(text="orbit options")
|
||||||
|
layout.prop(input_prefs, "ndof_orbit_invert_axes")
|
||||||
|
|
||||||
|
layout.separator()
|
||||||
|
layout.label(text="fly options")
|
||||||
|
layout.prop(input_prefs, "ndof_fly_helicopter", icon='NDOF_FLY')
|
||||||
|
layout.prop(input_prefs, "ndof_lock_horizon", icon='NDOF_DOM')
|
||||||
|
|
||||||
|
|
||||||
class USERPREF_PT_input(bpy.types.Panel, InputKeyMapPanel):
|
class USERPREF_PT_input(bpy.types.Panel, InputKeyMapPanel):
|
||||||
bl_space_type = 'USER_PREFERENCES'
|
bl_space_type = 'USER_PREFERENCES'
|
||||||
bl_label = _("Input")
|
bl_label = _("Input")
|
||||||
@@ -817,12 +842,9 @@ class USERPREF_PT_input(bpy.types.Panel, InputKeyMapPanel):
|
|||||||
#sub.prop(view, "wheel_scroll_lines", text="Scroll Lines")
|
#sub.prop(view, "wheel_scroll_lines", text="Scroll Lines")
|
||||||
|
|
||||||
col.separator()
|
col.separator()
|
||||||
''' not implemented yet
|
|
||||||
sub = col.column()
|
sub = col.column()
|
||||||
sub.label(text="NDOF Device:")
|
sub.label(text="NDOF Device:")
|
||||||
sub.prop(inputs, "ndof_pan_speed", text="Pan Speed")
|
sub.prop(inputs, "ndof_sensitivity", text="NDOF Sensitivity")
|
||||||
sub.prop(inputs, "ndof_rotate_speed", text="Orbit Speed")
|
|
||||||
'''
|
|
||||||
|
|
||||||
row.separator()
|
row.separator()
|
||||||
|
|
||||||
@@ -881,7 +903,7 @@ class USERPREF_PT_addons(bpy.types.Panel):
|
|||||||
if not user_addon_paths:
|
if not user_addon_paths:
|
||||||
user_script_path = bpy.utils.user_script_path()
|
user_script_path = bpy.utils.user_script_path()
|
||||||
if user_script_path is not None:
|
if user_script_path is not None:
|
||||||
user_addon_paths.append(os.path.join(user_script_path(), "addons"))
|
user_addon_paths.append(os.path.join(user_script_path, "addons"))
|
||||||
user_addon_paths.append(os.path.join(bpy.utils.resource_path('USER'), "scripts", "addons"))
|
user_addon_paths.append(os.path.join(bpy.utils.resource_path('USER'), "scripts", "addons"))
|
||||||
|
|
||||||
for path in user_addon_paths:
|
for path in user_addon_paths:
|
||||||
@@ -927,6 +949,12 @@ class USERPREF_PT_addons(bpy.types.Panel):
|
|||||||
"(see console for details)",
|
"(see console for details)",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if addon_utils.error_encoding:
|
||||||
|
self.draw_error(col,
|
||||||
|
"One or more addons do not have UTF-8 encoding\n"
|
||||||
|
"(see console for details)",
|
||||||
|
)
|
||||||
|
|
||||||
filter = context.window_manager.addon_filter
|
filter = context.window_manager.addon_filter
|
||||||
search = context.window_manager.addon_search.lower()
|
search = context.window_manager.addon_search.lower()
|
||||||
support = context.window_manager.addon_support
|
support = context.window_manager.addon_support
|
||||||
@@ -1020,7 +1048,6 @@ class USERPREF_PT_addons(bpy.types.Panel):
|
|||||||
for i in range(4 - tot_row):
|
for i in range(4 - tot_row):
|
||||||
split.separator()
|
split.separator()
|
||||||
|
|
||||||
|
|
||||||
# Append missing scripts
|
# Append missing scripts
|
||||||
# First collect scripts that are used but have no script file.
|
# First collect scripts that are used but have no script file.
|
||||||
module_names = {mod.__name__ for mod, info in addons}
|
module_names = {mod.__name__ for mod, info in addons}
|
||||||
@@ -1049,17 +1076,25 @@ class WM_OT_addon_enable(bpy.types.Operator):
|
|||||||
bl_idname = "wm.addon_enable"
|
bl_idname = "wm.addon_enable"
|
||||||
bl_label = _("Enable Add-On")
|
bl_label = _("Enable Add-On")
|
||||||
|
|
||||||
module = StringProperty(name=_("Module"), description=_("Module name of the addon to enable"))
|
module = StringProperty(
|
||||||
|
name=_("Module"),
|
||||||
|
description=_("Module name of the addon to enable"),
|
||||||
|
)
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
mod = addon_utils.enable(self.module)
|
mod = addon_utils.enable(self.module)
|
||||||
|
|
||||||
if mod:
|
if mod:
|
||||||
# check if add-on is written for current blender version, or raise a warning
|
|
||||||
info = addon_utils.module_bl_info(mod)
|
info = addon_utils.module_bl_info(mod)
|
||||||
|
|
||||||
if info.get("blender", (0, 0, 0)) > bpy.app.version:
|
info_ver = info.get("blender", (0, 0, 0))
|
||||||
self.report("WARNING','This script was written for a newer version of Blender and might not function (correctly).\nThe script is enabled though.")
|
|
||||||
|
if info_ver > bpy.app.version:
|
||||||
|
self.report({'WARNING'}, ("This script was written Blender "
|
||||||
|
"version %d.%d.%d and might not "
|
||||||
|
"function (correctly).\n"
|
||||||
|
"The script is enabled though.") %
|
||||||
|
info_ver)
|
||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
else:
|
else:
|
||||||
return {'CANCELLED'}
|
return {'CANCELLED'}
|
||||||
|
@@ -190,10 +190,10 @@ class InputKeyMapPanel:
|
|||||||
|
|
||||||
if km.is_modal:
|
if km.is_modal:
|
||||||
row.label(text="", icon='LINKED')
|
row.label(text="", icon='LINKED')
|
||||||
if km.is_user_defined:
|
if km.is_user_modified:
|
||||||
row.operator("wm.keymap_restore", text=_("Restore"))
|
row.operator("wm.keymap_restore", text=_("Restore"))
|
||||||
else:
|
else:
|
||||||
row.operator("wm.keymap_edit", text=_("Edit"))
|
row.label()
|
||||||
|
|
||||||
if km.show_expanded_children:
|
if km.show_expanded_children:
|
||||||
if children:
|
if children:
|
||||||
@@ -214,7 +214,6 @@ class InputKeyMapPanel:
|
|||||||
# "Add New" at end of keymap item list
|
# "Add New" at end of keymap item list
|
||||||
col = self.indented_layout(col, level + 1)
|
col = self.indented_layout(col, level + 1)
|
||||||
subcol = col.split(percentage=0.2).column()
|
subcol = col.split(percentage=0.2).column()
|
||||||
subcol.enabled = km.is_user_defined
|
|
||||||
subcol.operator("wm.keyitem_add", text=_("Add New"), icon='ZOOMIN')
|
subcol.operator("wm.keyitem_add", text=_("Add New"), icon='ZOOMIN')
|
||||||
|
|
||||||
col.separator()
|
col.separator()
|
||||||
@@ -245,7 +244,7 @@ class InputKeyMapPanel:
|
|||||||
|
|
||||||
col = self.indented_layout(layout, level)
|
col = self.indented_layout(layout, level)
|
||||||
|
|
||||||
if km.is_user_defined:
|
if kmi.show_expanded:
|
||||||
col = col.column(align=True)
|
col = col.column(align=True)
|
||||||
box = col.box()
|
box = col.box()
|
||||||
else:
|
else:
|
||||||
@@ -258,7 +257,6 @@ class InputKeyMapPanel:
|
|||||||
row.prop(kmi, "show_expanded", text="", emboss=False)
|
row.prop(kmi, "show_expanded", text="", emboss=False)
|
||||||
|
|
||||||
row = split.row()
|
row = split.row()
|
||||||
row.enabled = km.is_user_defined
|
|
||||||
row.prop(kmi, "active", text="", emboss=False)
|
row.prop(kmi, "active", text="", emboss=False)
|
||||||
|
|
||||||
if km.is_modal:
|
if km.is_modal:
|
||||||
@@ -267,12 +265,13 @@ class InputKeyMapPanel:
|
|||||||
row.label(text=kmi.name)
|
row.label(text=kmi.name)
|
||||||
|
|
||||||
row = split.row()
|
row = split.row()
|
||||||
row.enabled = km.is_user_defined
|
|
||||||
row.prop(kmi, "map_type", text="")
|
row.prop(kmi, "map_type", text="")
|
||||||
if map_type == 'KEYBOARD':
|
if map_type == 'KEYBOARD':
|
||||||
row.prop(kmi, "type", text="", full_event=True)
|
row.prop(kmi, "type", text="", full_event=True)
|
||||||
elif map_type == 'MOUSE':
|
elif map_type == 'MOUSE':
|
||||||
row.prop(kmi, "type", text="", full_event=True)
|
row.prop(kmi, "type", text="", full_event=True)
|
||||||
|
elif map_type == 'NDOF':
|
||||||
|
row.prop(kmi, "type", text="", full_event=True)
|
||||||
elif map_type == 'TWEAK':
|
elif map_type == 'TWEAK':
|
||||||
subrow = row.row()
|
subrow = row.row()
|
||||||
subrow.prop(kmi, "type", text="")
|
subrow.prop(kmi, "type", text="")
|
||||||
@@ -282,9 +281,10 @@ class InputKeyMapPanel:
|
|||||||
else:
|
else:
|
||||||
row.label()
|
row.label()
|
||||||
|
|
||||||
if not kmi.is_user_defined:
|
if (not kmi.is_user_defined) and kmi.is_user_modified:
|
||||||
op = row.operator("wm.keyitem_restore", text="", icon='BACK')
|
op = row.operator("wm.keyitem_restore", text="", icon='BACK')
|
||||||
op.item_id = kmi.id
|
op.item_id = kmi.id
|
||||||
|
else:
|
||||||
op = row.operator("wm.keyitem_remove", text="", icon='X')
|
op = row.operator("wm.keyitem_remove", text="", icon='X')
|
||||||
op.item_id = kmi.id
|
op.item_id = kmi.id
|
||||||
|
|
||||||
@@ -292,8 +292,6 @@ class InputKeyMapPanel:
|
|||||||
if kmi.show_expanded:
|
if kmi.show_expanded:
|
||||||
box = col.box()
|
box = col.box()
|
||||||
|
|
||||||
box.enabled = km.is_user_defined
|
|
||||||
|
|
||||||
if map_type not in {'TEXTINPUT', 'TIMER'}:
|
if map_type not in {'TEXTINPUT', 'TIMER'}:
|
||||||
split = box.split(percentage=0.4)
|
split = box.split(percentage=0.4)
|
||||||
sub = split.row()
|
sub = split.row()
|
||||||
@@ -308,7 +306,7 @@ class InputKeyMapPanel:
|
|||||||
sub = split.column()
|
sub = split.column()
|
||||||
subrow = sub.row(align=True)
|
subrow = sub.row(align=True)
|
||||||
|
|
||||||
if map_type == 'KEYBOARD':
|
if map_type in {'KEYBOARD', 'NDOF'}:
|
||||||
subrow.prop(kmi, "type", text="", event=True)
|
subrow.prop(kmi, "type", text="", event=True)
|
||||||
subrow.prop(kmi, "value", text="")
|
subrow.prop(kmi, "value", text="")
|
||||||
elif map_type == 'MOUSE':
|
elif map_type == 'MOUSE':
|
||||||
@@ -352,10 +350,10 @@ class InputKeyMapPanel:
|
|||||||
row.label()
|
row.label()
|
||||||
row.label()
|
row.label()
|
||||||
|
|
||||||
if km.is_user_defined:
|
if km.is_user_modified:
|
||||||
row.operator("wm.keymap_restore", text=_("Restore"))
|
row.operator("wm.keymap_restore", text=_("Restore"))
|
||||||
else:
|
else:
|
||||||
row.operator("wm.keymap_edit", text=_("Edit"))
|
row.label()
|
||||||
|
|
||||||
for kmi in filtered_items:
|
for kmi in filtered_items:
|
||||||
self.draw_kmi(display_keymaps, kc, km, kmi, col, 1)
|
self.draw_kmi(display_keymaps, kc, km, kmi, col, 1)
|
||||||
@@ -363,7 +361,6 @@ class InputKeyMapPanel:
|
|||||||
# "Add New" at end of keymap item list
|
# "Add New" at end of keymap item list
|
||||||
col = self.indented_layout(layout, 1)
|
col = self.indented_layout(layout, 1)
|
||||||
subcol = col.split(percentage=0.2).column()
|
subcol = col.split(percentage=0.2).column()
|
||||||
subcol.enabled = km.is_user_defined
|
|
||||||
subcol.operator("wm.keyitem_add", text=_("Add New"), icon='ZOOMIN')
|
subcol.operator("wm.keyitem_add", text=_("Add New"), icon='ZOOMIN')
|
||||||
|
|
||||||
def draw_hierarchy(self, display_keymaps, layout):
|
def draw_hierarchy(self, display_keymaps, layout):
|
||||||
@@ -372,8 +369,7 @@ class InputKeyMapPanel:
|
|||||||
|
|
||||||
def draw_keymaps(self, context, layout):
|
def draw_keymaps(self, context, layout):
|
||||||
wm = context.window_manager
|
wm = context.window_manager
|
||||||
kc = wm.keyconfigs.active
|
kc = wm.keyconfigs.user
|
||||||
defkc = wm.keyconfigs.default
|
|
||||||
|
|
||||||
col = layout.column()
|
col = layout.column()
|
||||||
sub = col.column()
|
sub = col.column()
|
||||||
@@ -398,7 +394,7 @@ class InputKeyMapPanel:
|
|||||||
|
|
||||||
col.separator()
|
col.separator()
|
||||||
|
|
||||||
display_keymaps = _merge_keymaps(kc, defkc)
|
display_keymaps = _merge_keymaps(kc, kc)
|
||||||
if context.space_data.filter_text != "":
|
if context.space_data.filter_text != "":
|
||||||
filter_text = context.space_data.filter_text.lower()
|
filter_text = context.space_data.filter_text.lower()
|
||||||
self.draw_filtered(display_keymaps, filter_text, col)
|
self.draw_filtered(display_keymaps, filter_text, col)
|
||||||
@@ -550,22 +546,24 @@ class WM_OT_keyconfig_import(bpy.types.Operator):
|
|||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
from os.path import basename
|
from os.path import basename
|
||||||
import shutil
|
import shutil
|
||||||
if not self.filepath:
|
|
||||||
raise Exception("Filepath not set")
|
|
||||||
|
|
||||||
f = open(self.filepath, "r")
|
if not self.filepath:
|
||||||
if not f:
|
self.report({'ERROR'}, "Filepath not set")
|
||||||
raise Exception("Could not open file")
|
return {'CANCELLED'}
|
||||||
|
|
||||||
config_name = basename(self.filepath)
|
config_name = basename(self.filepath)
|
||||||
|
|
||||||
path = bpy.utils.user_resource('SCRIPTS', os.path.join("presets", "keyconfig"), create=True)
|
path = bpy.utils.user_resource('SCRIPTS', os.path.join("presets", "keyconfig"), create=True)
|
||||||
path = os.path.join(path, config_name)
|
path = os.path.join(path, config_name)
|
||||||
|
|
||||||
|
try:
|
||||||
if self.keep_original:
|
if self.keep_original:
|
||||||
shutil.copy(self.filepath, path)
|
shutil.copy(self.filepath, path)
|
||||||
else:
|
else:
|
||||||
shutil.move(self.filepath, path)
|
shutil.move(self.filepath, path)
|
||||||
|
except Exception as e:
|
||||||
|
self.report({'ERROR'}, "Installing keymap failed: %s" % e)
|
||||||
|
return {'CANCELLED'}
|
||||||
|
|
||||||
# sneaky way to check we're actually running the code.
|
# sneaky way to check we're actually running the code.
|
||||||
bpy.utils.keyconfig_set(path)
|
bpy.utils.keyconfig_set(path)
|
||||||
@@ -595,6 +593,9 @@ class WM_OT_keyconfig_export(bpy.types.Operator):
|
|||||||
if not self.filepath:
|
if not self.filepath:
|
||||||
raise Exception("Filepath not set")
|
raise Exception("Filepath not set")
|
||||||
|
|
||||||
|
if not self.filepath.endswith('.py'):
|
||||||
|
self.filepath += '.py'
|
||||||
|
|
||||||
f = open(self.filepath, "w")
|
f = open(self.filepath, "w")
|
||||||
if not f:
|
if not f:
|
||||||
raise Exception("Could not open file")
|
raise Exception("Could not open file")
|
||||||
@@ -609,7 +610,7 @@ class WM_OT_keyconfig_export(bpy.types.Operator):
|
|||||||
|
|
||||||
# Generate a list of keymaps to export:
|
# Generate a list of keymaps to export:
|
||||||
#
|
#
|
||||||
# First add all user_defined keymaps (found in inputs.edited_keymaps list),
|
# First add all user_modified keymaps (found in keyconfigs.user.keymaps list),
|
||||||
# then add all remaining keymaps from the currently active custom keyconfig.
|
# then add all remaining keymaps from the currently active custom keyconfig.
|
||||||
#
|
#
|
||||||
# This will create a final list of keymaps that can be used as a 'diff' against
|
# This will create a final list of keymaps that can be used as a 'diff' against
|
||||||
@@ -619,7 +620,9 @@ class WM_OT_keyconfig_export(bpy.types.Operator):
|
|||||||
class FakeKeyConfig():
|
class FakeKeyConfig():
|
||||||
keymaps = []
|
keymaps = []
|
||||||
edited_kc = FakeKeyConfig()
|
edited_kc = FakeKeyConfig()
|
||||||
edited_kc.keymaps.extend(context.user_preferences.inputs.edited_keymaps)
|
for km in wm.keyconfigs.user.keymaps:
|
||||||
|
if km.is_user_modified:
|
||||||
|
edited_kc.keymaps.append(km)
|
||||||
# merge edited keymaps with non-default keyconfig, if it exists
|
# merge edited keymaps with non-default keyconfig, if it exists
|
||||||
if kc != wm.keyconfigs.default:
|
if kc != wm.keyconfigs.default:
|
||||||
export_keymaps = _merge_keymaps(edited_kc, kc)
|
export_keymaps = _merge_keymaps(edited_kc, kc)
|
||||||
@@ -669,18 +672,6 @@ class WM_OT_keyconfig_export(bpy.types.Operator):
|
|||||||
return {'RUNNING_MODAL'}
|
return {'RUNNING_MODAL'}
|
||||||
|
|
||||||
|
|
||||||
class WM_OT_keymap_edit(bpy.types.Operator):
|
|
||||||
"Edit stored key map"
|
|
||||||
bl_idname = "wm.keymap_edit"
|
|
||||||
bl_label = _("Edit Key Map")
|
|
||||||
__doc__ = _("Edit stored key map")
|
|
||||||
|
|
||||||
def execute(self, context):
|
|
||||||
km = context.keymap
|
|
||||||
km.copy_to_user()
|
|
||||||
return {'FINISHED'}
|
|
||||||
|
|
||||||
|
|
||||||
class WM_OT_keymap_restore(bpy.types.Operator):
|
class WM_OT_keymap_restore(bpy.types.Operator):
|
||||||
"Restore key map(s)"
|
"Restore key map(s)"
|
||||||
bl_idname = "wm.keymap_restore"
|
bl_idname = "wm.keymap_restore"
|
||||||
@@ -693,7 +684,7 @@ class WM_OT_keymap_restore(bpy.types.Operator):
|
|||||||
wm = context.window_manager
|
wm = context.window_manager
|
||||||
|
|
||||||
if self.all:
|
if self.all:
|
||||||
for km in wm.keyconfigs.default.keymaps:
|
for km in wm.keyconfigs.user.keymaps:
|
||||||
km.restore_to_default()
|
km.restore_to_default()
|
||||||
else:
|
else:
|
||||||
km = context.keymap
|
km = context.keymap
|
||||||
@@ -713,13 +704,13 @@ class WM_OT_keyitem_restore(bpy.types.Operator):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def poll(cls, context):
|
def poll(cls, context):
|
||||||
keymap = getattr(context, "keymap", None)
|
keymap = getattr(context, "keymap", None)
|
||||||
return keymap and keymap.is_user_defined
|
return keymap
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
km = context.keymap
|
km = context.keymap
|
||||||
kmi = km.keymap_items.from_id(self.item_id)
|
kmi = km.keymap_items.from_id(self.item_id)
|
||||||
|
|
||||||
if not kmi.is_user_defined:
|
if (not kmi.is_user_defined) and kmi.is_user_modified:
|
||||||
km.restore_item_to_default(kmi)
|
km.restore_item_to_default(kmi)
|
||||||
|
|
||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
@@ -758,7 +749,7 @@ class WM_OT_keyitem_remove(bpy.types.Operator):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def poll(cls, context):
|
def poll(cls, context):
|
||||||
return hasattr(context, "keymap") and context.keymap.is_user_defined
|
return hasattr(context, "keymap")
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
km = context.keymap
|
km = context.keymap
|
||||||
|
@@ -59,6 +59,7 @@ def draw_gpencil_tools(context, layout):
|
|||||||
row = col.row()
|
row = col.row()
|
||||||
row.prop(context.tool_settings, "use_grease_pencil_sessions")
|
row.prop(context.tool_settings, "use_grease_pencil_sessions")
|
||||||
|
|
||||||
|
|
||||||
# ********** default tools for objectmode ****************
|
# ********** default tools for objectmode ****************
|
||||||
|
|
||||||
class VIEW3D_PT_tools_objectmode(View3DPanel, bpy.types.Panel):
|
class VIEW3D_PT_tools_objectmode(View3DPanel, bpy.types.Panel):
|
||||||
@@ -88,8 +89,9 @@ class VIEW3D_PT_tools_objectmode(View3DPanel, bpy.types.Panel):
|
|||||||
|
|
||||||
col = layout.column(align=True)
|
col = layout.column(align=True)
|
||||||
col.label(text=_("Shading:"))
|
col.label(text=_("Shading:"))
|
||||||
col.operator("object.shade_smooth", text=_("Smooth"))
|
row = col.row(align=True)
|
||||||
col.operator("object.shade_flat", text=_("Flat"))
|
row.operator("object.shade_smooth", text=_("Smooth"))
|
||||||
|
row.operator("object.shade_flat", text=_("Flat"))
|
||||||
|
|
||||||
draw_keyframing_tools(context, layout)
|
draw_keyframing_tools(context, layout)
|
||||||
|
|
||||||
@@ -155,8 +157,9 @@ class VIEW3D_PT_tools_meshedit(View3DPanel, bpy.types.Panel):
|
|||||||
|
|
||||||
col = layout.column(align=True)
|
col = layout.column(align=True)
|
||||||
col.label(text="Shading:")
|
col.label(text="Shading:")
|
||||||
col.operator("mesh.faces_shade_smooth", text="Smooth")
|
row = col.row(align=True)
|
||||||
col.operator("mesh.faces_shade_flat", text="Flat")
|
row.operator("mesh.faces_shade_smooth", text="Smooth")
|
||||||
|
row.operator("mesh.faces_shade_flat", text="Flat")
|
||||||
|
|
||||||
draw_repeat_tools(context, layout)
|
draw_repeat_tools(context, layout)
|
||||||
|
|
||||||
|
@@ -35,7 +35,7 @@ def add_object(self, context):
|
|||||||
mesh.from_pydata(verts, edges, faces)
|
mesh.from_pydata(verts, edges, faces)
|
||||||
# useful for development when the mesh may be invalid.
|
# useful for development when the mesh may be invalid.
|
||||||
# mesh.validate(verbose=True)
|
# mesh.validate(verbose=True)
|
||||||
add_object_data(context, mesh_data, operator=self)
|
add_object_data(context, mesh, operator=self)
|
||||||
|
|
||||||
|
|
||||||
class OBJECT_OT_add_object(bpy.types.Operator, AddObjectHelper):
|
class OBJECT_OT_add_object(bpy.types.Operator, AddObjectHelper):
|
||||||
|
0
release/scripts/templates/batch_export.py
Executable file → Normal file
0
release/scripts/templates/batch_export.py
Executable file → Normal file
@@ -18,7 +18,7 @@ class ModalOperator(bpy.types.Operator):
|
|||||||
elif event.type == 'LEFTMOUSE':
|
elif event.type == 'LEFTMOUSE':
|
||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
|
|
||||||
elif event.type in ('RIGHTMOUSE', 'ESC'):
|
elif event.type in {'RIGHTMOUSE', 'ESC'}:
|
||||||
context.object.location.x = self.first_value
|
context.object.location.x = self.first_value
|
||||||
return {'CANCELLED'}
|
return {'CANCELLED'}
|
||||||
|
|
||||||
|
@@ -45,7 +45,7 @@ class ModalDrawOperator(bpy.types.Operator):
|
|||||||
context.region.callback_remove(self._handle)
|
context.region.callback_remove(self._handle)
|
||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
|
|
||||||
elif event.type in ('RIGHTMOUSE', 'ESC'):
|
elif event.type in {'RIGHTMOUSE', 'ESC'}:
|
||||||
context.region.callback_remove(self._handle)
|
context.region.callback_remove(self._handle)
|
||||||
return {'CANCELLED'}
|
return {'CANCELLED'}
|
||||||
|
|
||||||
|
@@ -29,7 +29,7 @@ class ViewOperator(bpy.types.Operator):
|
|||||||
context.area.header_text_set()
|
context.area.header_text_set()
|
||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
|
|
||||||
elif event.type in ('RIGHTMOUSE', 'ESC'):
|
elif event.type in {'RIGHTMOUSE', 'ESC'}:
|
||||||
rv3d.view_location = self._initial_location
|
rv3d.view_location = self._initial_location
|
||||||
context.area.header_text_set()
|
context.area.header_text_set()
|
||||||
return {'CANCELLED'}
|
return {'CANCELLED'}
|
||||||
|
0
release/scripts/templates/ui_menu.py
Executable file → Normal file
0
release/scripts/templates/ui_menu.py
Executable file → Normal file
@@ -12,22 +12,22 @@
|
|||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<p class="title"><b>Blender 2.58</b></p>
|
<p class="title"><b>Blender 2.59</b></p>
|
||||||
<p><br></p>
|
<p><br></p>
|
||||||
<p class="header"><b>About</b></p>
|
<p class="header"><b>About</b></p>
|
||||||
<p class="body">Welcome to Blender, the free, open source 3D application for modeling, animation, rendering, compositing, video editing and game creation. Blender is available for Linux, Mac OS X, Windows, Solaris and FreeBSD and has a large world-wide community.</p>
|
<p class="body">Welcome to Blender, the free, open source 3D application for modeling, animation, rendering, compositing, video editing and game creation. Blender is available for Linux, Mac OS X, Windows, Solaris and FreeBSD and has a large world-wide community.</p>
|
||||||
<p class="body">Blender can be used freely for any purpose, including commercial use and distribution. It's free and open-source software, released under the GNU GPL licence. The entire source code is available on our website.</p>
|
<p class="body">Blender can be used freely for any purpose, including commercial use and distribution. It's free and open-source software, released under the GNU GPL licence. The entire source code is available on our website.</p>
|
||||||
<p class="body">For more information, visit <a href="http://www.blender.org">blender.org</a>.</p>
|
<p class="body">For more information, visit <a href="http://www.blender.org">blender.org</a>.</p>
|
||||||
<p><br></p>
|
<p><br></p>
|
||||||
<p class="header"><b>2.58</b></p>
|
<p class="header"><b>2.59</b></p>
|
||||||
<p class="body">The Blender Foundation and online developer community is proud to present Blender 2.58. This release is the second official stable release of the Blender 2.5 series, and represents the culmination of many years of redesign and development work. <a href="http://www.blender.org/development/release-logs/blender-258/">More information about this release</a>.</p>
|
<p class="body">The Blender Foundation and online developer community is proud to present Blender 2.59. This release is the third official stable release of the Blender 2.5 series, and represents the culmination of many years of redesign and development work. <a href="http://www.blender.org/development/release-logs/blender-259/">More information about this release</a>.</p>
|
||||||
<p class="body">What to Expect:</p>
|
<p class="body">What to Expect:</p>
|
||||||
<p class="body"> • Big improvements - This is our most exciting version to date, already a significant improvement in many ways over 2.49</p>
|
<p class="body"> • Big improvements - This is our most exciting version to date, already a significant improvement in many ways over 2.49</p>
|
||||||
<p class="body"> • Missing/Incomplete Features - Although most of it is there, not all functionality from pre-2.5 versions has been restored yet. Some functionality may be re-implemented a different way.</p>
|
<p class="body"> • Missing/Incomplete Features - Although most of it is there, not all functionality from pre-2.5 versions has been restored yet. Some functionality may be re-implemented a different way.</p>
|
||||||
<p class="body"> • Changes - If you're used to the old Blenders, Blender 2.5 may seem quite different at first, but it won't be long before it grows on you even more than before.</p>
|
<p class="body"> • Changes - If you're used to the old Blenders, Blender 2.5 may seem quite different at first, but it won't be long before it grows on you even more than before.</p>
|
||||||
<p><br></p>
|
<p><br></p>
|
||||||
<p class="header"><b>Bugs</b></p>
|
<p class="header"><b>Bugs</b></p>
|
||||||
<p class="body">Although Blender 2.58 is considered a stable release, you may encounter a bug. If you do, please help us by posting it in the bug tracker or using Help → Report a Bug from inside Blender 2.58. If it wasn’t reported yet, please log in (or register) and fill in detailed information about the error. Please post detailed instructions on how to reproduce it or post a .blend file showcasing the bug.</p>
|
<p class="body">Although Blender 2.59 is considered a stable release, you may encounter a bug. If you do, please help us by posting it in the bug tracker or using Help → Report a Bug from inside Blender 2.59. If it wasn’t reported yet, please log in (or register) and fill in detailed information about the error. Please post detailed instructions on how to reproduce it or post a .blend file showcasing the bug.</p>
|
||||||
<p><br></p>
|
<p><br></p>
|
||||||
<p class="header"><b>Package Contents</b></p>
|
<p class="header"><b>Package Contents</b></p>
|
||||||
<p class="body">The downloaded Blender package includes:</p>
|
<p class="body">The downloaded Blender package includes:</p>
|
||||||
@@ -51,11 +51,11 @@
|
|||||||
<p class="header"><b>Links</b></p>
|
<p class="header"><b>Links</b></p>
|
||||||
<p class="body">Users:</p>
|
<p class="body">Users:</p>
|
||||||
<p class="body"> General information <a href="http://www.blender.org">www.blender.org</a> <br>
|
<p class="body"> General information <a href="http://www.blender.org">www.blender.org</a> <br>
|
||||||
Full release log <a href="http://www.blender.org/development/release-logs/blender-258/">www.blender.org/development/release-logs/blender-258/</a><br>
|
Full release log <a href="http://www.blender.org/development/release-logs/blender-259/">www.blender.org/development/release-logs/blender-259/</a><br>
|
||||||
Tutorials <a href="http://www.blender.org/education-help/">www.blender.org/education-help/</a> <br>
|
Tutorials <a href="http://www.blender.org/education-help/">www.blender.org/education-help/</a> <br>
|
||||||
Manual <a href="http://wiki.blender.org/index.php/Doc:Manual">wiki.blender.org/index.php/Doc:Manual</a><br>
|
Manual <a href="http://wiki.blender.org/index.php/Doc:Manual">wiki.blender.org/index.php/Doc:Manual</a><br>
|
||||||
User Forum <a href="http://www.blenderartists.org">www.blenderartists.org</a><br>
|
User Forum <a href="http://www.blenderartists.org">www.blenderartists.org</a><br>
|
||||||
IRC <a href="irc://irc.freenode.net/#blender">#blender on irc.freenode.net</a><br>
|
IRC <a href="irc://irc.freenode.net/#blenderchat">#blenderchat on irc.freenode.net</a><br>
|
||||||
</p>
|
</p>
|
||||||
<p class="body">Developers:</p>
|
<p class="body">Developers:</p>
|
||||||
<p class="body"> Development <a href="http://www.blender.org/development/">www.blender.org/development/</a><br>
|
<p class="body"> Development <a href="http://www.blender.org/development/">www.blender.org/development/</a><br>
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user