This commit is contained in:
2011-09-07 15:34:04 +00:00
1428 changed files with 156613 additions and 79067 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -35,17 +35,33 @@ OS_NCASE:=$(shell uname -s | tr '[A-Z]' '[a-z]')
# Source and Build DIR's
BLENDER_DIR:=$(shell pwd -P)
BUILD_DIR:=$(shell dirname $(BLENDER_DIR))/build/$(OS_NCASE)
BUILD_TYPE:=Release
BUILD_CMAKE_ARGS:=""
# -----------------------------------------------------------------------------
# additional targets for the build configuration
# support 'make debug'
ifneq "$(findstring debug, $(MAKECMDGOALS))" ""
BUILD_DIR:=$(BUILD_DIR)_debug
BUILD_TYPE:=Debug
else
BUILD_TYPE:=Release
endif
ifneq "$(findstring lite, $(MAKECMDGOALS))" ""
BUILD_DIR:=$(BUILD_DIR)_lite
BUILD_CMAKE_ARGS:=$(BUILD_CMAKE_ARGS) -C$(BLENDER_DIR)/build_files/cmake/config/blender_lite.cmake
endif
ifneq "$(findstring headless, $(MAKECMDGOALS))" ""
BUILD_DIR:=$(BUILD_DIR)_bpy
BUILD_CMAKE_ARGS:=$(BUILD_CMAKE_ARGS) -C$(BLENDER_DIR)/build_files/cmake/config/blender_headless.cmake
endif
ifneq "$(findstring bpy, $(MAKECMDGOALS))" ""
BUILD_DIR:=$(BUILD_DIR)_bpy
BUILD_CMAKE_ARGS:=$(BUILD_CMAKE_ARGS) -C$(BLENDER_DIR)/build_files/cmake/config/bpy_module.cmake
endif
# -----------------------------------------------------------------------------
# Get the number of cores for threaded build
NPROCS:=1
ifeq ($(OS), Linux)
@@ -61,27 +77,59 @@ ifeq ($(OS), NetBSD)
NPROCS:=$(shell sysctl -a | grep "hw.ncpu " | cut -d" " -f3 )
endif
# -----------------------------------------------------------------------------
# Build Blender
all:
@echo
@echo Configuring Blender ...
if test ! -f $(BUILD_DIR)/CMakeCache.txt ; then \
cmake -H$(BLENDER_DIR) -B$(BUILD_DIR) -DCMAKE_BUILD_TYPE:STRING=$(BUILD_TYPE) ; \
cmake $(BUILD_CMAKE_ARGS) -H$(BLENDER_DIR) -B$(BUILD_DIR) -DCMAKE_BUILD_TYPE:STRING=$(BUILD_TYPE); \
fi
@echo
@echo Building Blender ...
make -C $(BUILD_DIR) -s -j $(NPROCS) install
$(MAKE) -C $(BUILD_DIR) -s -j $(NPROCS) install
@echo
@echo run blender from "$(BUILD_DIR)/bin/blender"
@echo edit build configuration with: "$(BUILD_DIR)/CMakeCache.txt" run make again to rebuild.
@echo blender installed, run from: "$(BUILD_DIR)/bin/blender"
@echo
debug: all
# pass
lite: all
headless: all
bpy: all
# package types
# -----------------------------------------------------------------------------
# Helo for build targets
help:
@echo ""
@echo "Convenience targets provided for building blender, (multiple at once can be used)"
@echo " * debug - build a debug binary"
@echo " * lite - disable non essential features for a smaller binary and faster build"
@echo " * headless - build without an interface (renderfarm or server automation)"
@echo " * bpy - build as a python module which can be loaded from python directly"
@echo ""
@echo "Project Files for IDE's"
@echo " * project_qtcreator - QtCreator Project Files"
@echo " * project_netbeans - NetBeans Project Files"
@echo " * project_eclipse - Eclipse CDT4 Project Files"
@echo ""
@echo "Package Targets"
@echo " * package_debian - build a debian package"
@echo " * package_pacman - build an arch linux pacmanpackage"
@echo " * package_archive - build an archive package"
@echo ""
@echo "Testing Targets (not assosiated with building blender)"
@echo " * test - run ctest, currently tests import/export, operator execution and that python modules load"
@echo " * test_cmake - runs our own cmake file checker which detects errors in the cmake file list definitions"
@echo " * test_pep8 - checks all python script are pep8 which are tagged to use the stricter formatting"
@echo " * test_deprecated - checks for deprecation tags in our code which may need to be removed"
@echo ""
# -----------------------------------------------------------------------------
# Packages
#
package_debian:
cd build_files/package_spec ; DEB_BUILD_OPTIONS="parallel=$(NPROCS)" sh ./build_debian.sh
@@ -92,21 +140,43 @@ package_archive:
make -C $(BUILD_DIR) -s package_archive
@echo archive in "$(BUILD_DIR)/release"
# forward build targets
# -----------------------------------------------------------------------------
# Tests
#
test:
cd $(BUILD_DIR) ; ctest . --output-on-failure
# run pep8 check check on scripts we distribute.
test_pep8:
python source/tests/pep8.py > test_pep8.log 2>&1
python3 source/tests/pep8.py > test_pep8.log 2>&1
@echo "written: test_pep8.log"
# run some checks on our cmakefiles.
test_cmake:
python build_files/cmake/cmake_consistency_check.py > test_cmake_consistency.log 2>&1
python3 build_files/cmake/cmake_consistency_check.py > test_cmake_consistency.log 2>&1
@echo "written: test_cmake_consistency.log"
# run deprecation tests, see if we have anything to remove.
test_deprecated:
python3 source/tests/check_deprecated.py
# -----------------------------------------------------------------------------
# Project Files
#
project_qtcreator:
python3 build_files/cmake/cmake_qtcreator_project.py $(BUILD_DIR)
project_netbeans:
python3 build_files/cmake/cmake_netbeans_project.py $(BUILD_DIR)
project_eclipse:
cmake -G"Eclipse CDT4 - Unix Makefiles" -H$(BLENDER_DIR) -B$(BUILD_DIR)
clean:
make -C $(BUILD_DIR) clean
$(MAKE) -C $(BUILD_DIR) clean
.PHONY: all

View File

@@ -111,6 +111,11 @@ btools.print_targets(B.targets, B.bc)
# handling cmd line arguments & config file
# bitness stuff
tempbitness = int(B.arguments.get('BF_BITNESS', bitness)) # default to bitness found as per starting python
if tempbitness in (32, 64): # only set if 32 or 64 has been given
bitness = int(tempbitness)
# first check cmdline for toolset and we create env to work on
quickie = B.arguments.get('BF_QUICK', None)
quickdebug = B.arguments.get('BF_QUICKDEBUG', None)
@@ -161,6 +166,13 @@ if sys.platform=='win32':
env.SConscriptChdir(0)
# Remove major kernel version from linux platform.
# After Linus switched kernel to new version model this major version
# shouldn't take much sense for building rules.
if re.match('linux[0-9]+', platform):
platform = 'linux'
crossbuild = B.arguments.get('BF_CROSS', None)
if crossbuild and platform not in ('win32-vc', 'win64-vc'):
platform = 'linuxcross'
@@ -241,12 +253,31 @@ if 'blenderlite' in B.targets:
target_env_defs['BF_BUILDINFO'] = False
target_env_defs['BF_NO_ELBEEM'] = True
target_env_defs['WITH_BF_PYTHON'] = False
target_env_defs['WITH_BF_3DMOUSE'] = False
# Merge blenderlite, let command line to override
for k,v in target_env_defs.iteritems():
if k not in B.arguments:
env[k] = v
# Extended OSX_SDK and 3D_CONNEXION_CLIENT_LIBRARY detection for OSX
if env['OURPLATFORM']=='darwin':
print B.bc.OKGREEN + "Detected Xcode version: -- " + B.bc.ENDC + env['XCODE_CUR_VER'][:9] + " --"
print "Available " + env['MACOSX_SDK_CHECK']
if not 'Mac OS X 10.5' in env['MACOSX_SDK_CHECK']:
print B.bc.OKGREEN + "MacOSX10.5.sdk not available:" + B.bc.ENDC + " using MacOSX10.6.sdk"
else:
print B.bc.OKGREEN + "Found recommended sdk :" + B.bc.ENDC + " using MacOSX10.5.sdk"
# for now, Mac builders must download and install the 3DxWare 10 Beta 4 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:
if 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
else:
env.Append(LINKFLAGS=['-weak_framework','3DconnexionClient'])
if env['WITH_BF_OPENMP'] == 1:
if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
@@ -306,9 +337,10 @@ if env['BF_NO_ELBEEM'] == 1:
env['CXXFLAGS'].append('-DDISABLE_ELBEEM')
env['CCFLAGS'].append('-DDISABLE_ELBEEM')
if env['WITH_BF_SDL'] == False and env['OURPLATFORM'] in ('win32-vc', 'win32-ming', 'win64-vc'):
env['PLATFORM_LINKFLAGS'].remove('/ENTRY:mainCRTStartup')
env['PLATFORM_LINKFLAGS'].append('/ENTRY:main')
# TODO, make optional
env['CPPFLAGS'].append('-DWITH_AUDASPACE')
env['CXXFLAGS'].append('-DWITH_AUDASPACE')
env['CCFLAGS'].append('-DWITH_AUDASPACE')
# lastly we check for root_build_dir ( we should not do before, otherwise we might do wrong builddir
B.root_build_dir = env['BF_BUILDDIR']
@@ -360,6 +392,23 @@ if not quickie and do_clean:
print B.bc.HEADER+'Already Clean, nothing to do.'+B.bc.ENDC
Exit()
# ensure python header is found since detection can fail, this could happen
# with _any_ library but since we used a fixed python version this tends to
# be most problematic.
if env['WITH_BF_PYTHON']:
py_h = os.path.join(Dir(env.subst('${BF_PYTHON_INC}')).abspath, "Python.h")
if not os.path.exists(py_h):
print("\nMissing: \"" + env.subst('${BF_PYTHON_INC}') + os.sep + "Python.h\",\n"
" Set 'BF_PYTHON_INC' to point "
"to a valid python include path.\n Containing "
"Python.h for python version \"" + env.subst('${BF_PYTHON_VERSION}') + "\"")
Exit()
del py_h
if not os.path.isdir ( B.root_build_dir):
os.makedirs ( B.root_build_dir )
os.makedirs ( B.root_build_dir + 'source' )
@@ -409,17 +458,18 @@ if B.arguments.get('BF_PRIORITYLIST', '0')=='1':
B.propose_priorities()
dobj = B.buildinfo(env, "dynamic") + B.resources
creob = B.creator(env)
thestatlibs, thelibincs = B.setup_staticlibs(env)
thesyslibs = B.setup_syslibs(env)
if 'blender' in B.targets or not env['WITH_BF_NOBLENDER']:
env.BlenderProg(B.root_build_dir, "blender", mainlist + thestatlibs + dobj, thesyslibs, [B.root_build_dir+'/lib'] + thelibincs, 'blender')
env.BlenderProg(B.root_build_dir, "blender", creob + mainlist + thestatlibs + dobj, thesyslibs, [B.root_build_dir+'/lib'] + thelibincs, 'blender')
if env['WITH_BF_PLAYER']:
playerlist = B.create_blender_liblist(env, 'player')
playerlist += B.create_blender_liblist(env, 'player2')
playerlist += B.create_blender_liblist(env, 'intern')
playerlist += B.create_blender_liblist(env, 'extern')
env.BlenderProg(B.root_build_dir, "blenderplayer", playerlist + thestatlibs + dobj, thesyslibs, [B.root_build_dir+'/lib'] + thelibincs, 'blenderplayer')
env.BlenderProg(B.root_build_dir, "blenderplayer", dobj + playerlist + thestatlibs, thesyslibs, [B.root_build_dir+'/lib'] + thelibincs, 'blenderplayer')
##### Now define some targets
@@ -508,7 +558,7 @@ if env['OURPLATFORM']!='darwin':
scriptinstall.append(env.Install(dir=dir,source=source))
#-- icons
if env['OURPLATFORM']=='linux2':
if env['OURPLATFORM']=='linux':
iconlist = []
icontargetlist = []
@@ -587,7 +637,7 @@ textinstall = env.Install(dir=env['BF_INSTALLDIR'], source=textlist)
if env['OURPLATFORM']=='darwin':
allinstall = [blenderinstall, plugininstall, textinstall]
elif env['OURPLATFORM']=='linux2':
elif env['OURPLATFORM']=='linux':
allinstall = [blenderinstall, dotblenderinstall, scriptinstall, plugininstall, textinstall, iconinstall]
else:
allinstall = [blenderinstall, dotblenderinstall, scriptinstall, plugininstall, textinstall]
@@ -639,11 +689,7 @@ if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'win64-vc', 'linuxcross'):
dllsources.append('${LCGDIR}/sndfile/lib/libsndfile-1.dll')
if env['WITH_BF_FFMPEG']:
dllsources += ['${BF_FFMPEG_LIBPATH}/avcodec-52.dll',
'${BF_FFMPEG_LIBPATH}/avformat-52.dll',
'${BF_FFMPEG_LIBPATH}/avdevice-52.dll',
'${BF_FFMPEG_LIBPATH}/avutil-50.dll',
'${BF_FFMPEG_LIBPATH}/swscale-0.dll']
dllsources += env['BF_FFMPEG_DLL'].split()
# Since the thumb handler is loaded by Explorer, architecture is
# strict: the x86 build fails on x64 Windows. We need to ship

View File

@@ -81,6 +81,12 @@ WITH_BF_STATICJEMALLOC = True
BF_JEMALLOC = '/home/sources/staticlibs/jemalloc'
BF_JEMALLOC_LIBPATH = '${BF_JEMALLOC}/lib32'
# Use 3d mouse library
WITH_BF_3DMOUSE = True
WITH_BF_STATIC3DMOUSE = True
BF_3DMOUSE = '/home/sources/staticlibs/spnav'
BF_3DMOUSE_LIBPATH = '${BF_3DMOUSE}/lib32'
# Compilation and optimization
BF_DEBUG = False
REL_CFLAGS = ['-O2']

View File

@@ -13,7 +13,18 @@ WITH_BF_STATICPYTHON = True
WITH_BF_COLLADA = False
# FFMPEG configuration
WITH_BF_FFMPEG = False
WITH_BF_FFMPEG = True
WITH_BF_STATICFFMPEG = True
BF_FFMPEG = '/home/sources/staticlibs/ffmpeg'
BF_FFMPEG_LIBPATH = '${BF_FFMPEG}/lib32'
BF_FFMPEG_LIB_STATIC = '${BF_FFMPEG_LIBPATH}/libavformat.a ${BF_FFMPEG_LIBPATH}/libswscale.a ' + \
'${BF_FFMPEG_LIBPATH}/libavcodec.a ${BF_FFMPEG_LIBPATH}/libavdevice.a ${BF_FFMPEG_LIBPATH}/libavutil.a ' + \
'${BF_FFMPEG_LIBPATH}/libxvidcore.a ${BF_FFMPEG_LIBPATH}/libx264.a ${BF_FFMPEG_LIBPATH}/libmp3lame.a ' + \
'${BF_FFMPEG_LIBPATH}/libvpx.a ${BF_FFMPEG_LIBPATH}/libvorbis.a ${BF_FFMPEG_LIBPATH}/libogg.a ' + \
'${BF_FFMPEG_LIBPATH}/libvorbisenc.a ${BF_FFMPEG_LIBPATH}/libtheora.a ' + \
'${BF_FFMPEG_LIBPATH}/libschroedinger-1.0.a ${BF_FFMPEG_LIBPATH}/liborc-0.4.a ${BF_FFMPEG_LIBPATH}/libdirac_encoder.a ' + \
'${BF_FFMPEG_LIBPATH}/libfaad.a'
# Don't depend on system's libstdc++
WITH_BF_STATICCXX = True
@@ -65,6 +76,12 @@ WITH_BF_STATICJEMALLOC = True
BF_JEMALLOC = '/home/sources/staticlibs/jemalloc'
BF_JEMALLOC_LIBPATH = '${BF_JEMALLOC}/lib32'
# Use 3d mouse library
WITH_BF_3DMOUSE = True
WITH_BF_STATIC3DMOUSE = True
BF_3DMOUSE = '/home/sources/staticlibs/spnav'
BF_3DMOUSE_LIBPATH = '${BF_3DMOUSE}/lib32'
# Compilation and optimization
BF_DEBUG = False
REL_CFLAGS = ['-O2']

View File

@@ -13,7 +13,18 @@ WITH_BF_STATICPYTHON = True
WITH_BF_COLLADA = False
# FFMPEG configuration
WITH_BF_FFMPEG = False
WITH_BF_FFMPEG = True
WITH_BF_STATICFFMPEG = True
BF_FFMPEG = '/home/sources/staticlibs/ffmpeg'
BF_FFMPEG_LIBPATH = '${BF_FFMPEG}/lib64'
BF_FFMPEG_LIB_STATIC = '${BF_FFMPEG_LIBPATH}/libavformat.a ${BF_FFMPEG_LIBPATH}/libswscale.a ' + \
'${BF_FFMPEG_LIBPATH}/libavcodec.a ${BF_FFMPEG_LIBPATH}/libavdevice.a ${BF_FFMPEG_LIBPATH}/libavutil.a ' + \
'${BF_FFMPEG_LIBPATH}/libxvidcore.a ${BF_FFMPEG_LIBPATH}/libx264.a ${BF_FFMPEG_LIBPATH}/libmp3lame.a ' + \
'${BF_FFMPEG_LIBPATH}/libvpx.a ${BF_FFMPEG_LIBPATH}/libvorbis.a ${BF_FFMPEG_LIBPATH}/libogg.a ' + \
'${BF_FFMPEG_LIBPATH}/libvorbisenc.a ${BF_FFMPEG_LIBPATH}/libtheora.a ' + \
'${BF_FFMPEG_LIBPATH}/libschroedinger-1.0.a ${BF_FFMPEG_LIBPATH}/liborc-0.4.a ${BF_FFMPEG_LIBPATH}/libdirac_encoder.a ' + \
'${BF_FFMPEG_LIBPATH}/libfaad.a'
# Don't depend on system's libstdc++
WITH_BF_STATICCXX = True
@@ -65,6 +76,12 @@ WITH_BF_STATICJEMALLOC = True
BF_JEMALLOC = '/home/sources/staticlibs/jemalloc'
BF_JEMALLOC_LIBPATH = '${BF_JEMALLOC}/lib64'
# Use 3d mouse library
WITH_BF_3DMOUSE = True
WITH_BF_STATIC3DMOUSE = True
BF_3DMOUSE = '/home/sources/staticlibs/spnav'
BF_3DMOUSE_LIBPATH = '${BF_3DMOUSE}/lib64'
# Compilation and optimization
BF_DEBUG = False
REL_CFLAGS = ['-O2']

View File

@@ -81,6 +81,12 @@ WITH_BF_STATICJEMALLOC = True
BF_JEMALLOC = '/home/sources/staticlibs/jemalloc'
BF_JEMALLOC_LIBPATH = '${BF_JEMALLOC}/lib64'
# Use 3d mouse library
WITH_BF_3DMOUSE = True
WITH_BF_STATIC3DMOUSE = True
BF_3DMOUSE = '/home/sources/staticlibs/spnav'
BF_3DMOUSE_LIBPATH = '${BF_3DMOUSE}/lib64'
# Compilation and optimization
BF_DEBUG = False
REL_CFLAGS = ['-O2']

View File

@@ -74,6 +74,7 @@ def svn_step(branch=''):
else:
return SVN(baseURL='https://svn.blender.org/svnroot/bf-blender/%%BRANCH%%/blender', mode='update', defaultBranch='trunk', workdir='blender')
def lib_svn_step(dir):
return SVN(name='lib svn', baseURL='https://svn.blender.org/svnroot/bf-blender/%%BRANCH%%/lib/' + dir, mode='update', defaultBranch='trunk', workdir='lib/' + dir)
@@ -115,6 +116,7 @@ add_builder(c, 'linux_x86_64_scons', '', generic_builder)
add_builder(c, 'salad_linux_x86_64_scons', '', generic_builder, 'soc-2011-salad')
add_builder(c, 'win32_scons', 'windows', generic_builder)
add_builder(c, 'salad_win32_scons', 'windows', generic_builder, 'soc-2011-salad')
add_builder(c, 'win64_scons', 'win64', generic_builder)
#add_builder(c, 'freebsd_i386_cmake', '', generic_builder)
#add_builder(c, 'freebsd_x86_64_cmake', '', generic_builder)

View File

@@ -64,10 +64,11 @@ def get_platform(filename):
return '-'.join(platform_tokens)
def get_branch(filename):
tokens = filename.split("-")
branch = ""
for token in tokens:
if branch == "":
branch = token

View File

@@ -108,5 +108,13 @@ else:
sys.exit(0)
else:
if builder.find('win') != -1:
bitness = '32'
if builder.find('win64') != -1:
bitness = '64'
scons_options.append('BF_BITNESS=' + bitness)
retcode = subprocess.call(['python', 'scons/scons.py'] + scons_options)
sys.exit(retcode)

View File

@@ -36,7 +36,7 @@ builder = sys.argv[1]
branch = ''
if len(sys.argv) >= 3:
branch = sys.argv[2]
branch = sys.argv[2]
# scons does own packaging
if builder.find('scons') != -1:
@@ -72,6 +72,14 @@ if builder.find('scons') != -1:
retcode = subprocess.call(['python', 'scons/scons.py'] + scons_options)
sys.exit(retcode)
else:
if builder.find('win') != -1:
bitness = '32'
if builder.find('win64') != -1:
bitness = '64'
scons_options.append('BF_BITNESS=' + bitness)
retcode = subprocess.call(['python', 'scons/scons.py'] + scons_options)
sys.exit(retcode)

View File

@@ -1,72 +0,0 @@
# - Find python libraries
#
# PYTHON_VERSION
# PYTHON_INCLUDE_DIRS
# PYTHON_LIBRARY
# PYTHON_LIBPATH
# PYTHON_LINKFLAGS
#=============================================================================
set(PYTHON_VERSION 3.2 CACHE STRING "")
mark_as_advanced(PYTHON_VERSION)
set(PYTHON_LINKFLAGS "-Xlinker -export-dynamic")
mark_as_advanced(PYTHON_LINKFLAGS)
set(_Python_ABI_FLAGS
"m;mu;u; ")
string(REPLACE "." "" _PYTHON_VERSION_NO_DOTS ${PYTHON_VERSION})
set(_Python_PATHS
"$ENV{HOME}/py${_PYTHON_VERSION_NO_DOTS}" "/opt/py${_PYTHON_VERSION_NO_DOTS}" "/usr" "/usr/local")
if(NOT DEFINED PYTHON_INCLUDE_DIRS)
message(STATUS "Looking for include Python.h")
set(_Found_PYTHON_H OFF)
foreach(_CURRENT_PATH ${_Python_PATHS})
foreach(_CURRENT_ABI_FLAGS ${_Python_ABI_FLAGS})
if(CMAKE_BUILD_TYPE STREQUAL Debug)
set(_CURRENT_ABI_FLAGS "d${_CURRENT_ABI_FLAGS}")
endif()
string(REPLACE " " "" _CURRENT_ABI_FLAGS ${_CURRENT_ABI_FLAGS})
set(_Python_HEADER "${_CURRENT_PATH}/include/python${PYTHON_VERSION}${_CURRENT_ABI_FLAGS}/Python.h")
if(EXISTS ${_Python_HEADER})
message(STATUS "Checking for header: ${_Python_HEADER} - found")
set(_Found_PYTHON_H ON)
set(PYTHON ${_CURRENT_PATH})
set(PYTHON_ABI_FLAGS ${_CURRENT_ABI_FLAGS})
break()
else()
message(STATUS "Checking for header: ${_Python_HEADER}")
endif()
endforeach()
if(_Found_PYTHON_H)
break()
endif()
endforeach()
if(NOT _Found_PYTHON_H)
message(FATAL_ERROR "Python.h not found")
endif()
endif()
#=============================================================================
# now the python versions are found
set(PYTHON_INCLUDE_DIRS "${PYTHON}/include/python${PYTHON_VERSION}${PYTHON_ABI_FLAGS}" CACHE STRING "")
mark_as_advanced(PYTHON_INCLUDE_DIRS)
set(PYTHON_LIBRARY "python${PYTHON_VERSION}${PYTHON_ABI_FLAGS}" CACHE STRING "")
mark_as_advanced(PYTHON_LIBRARY)
set(PYTHON_LIBPATH ${PYTHON}/lib CACHE STRING "")
mark_as_advanced(PYTHON_LIBPATH)
# set(PYTHON_BINARY ${PYTHON_EXECUTABLE} CACHE STRING "")
if(NOT EXISTS "${PYTHON_INCLUDE_DIRS}/Python.h")
message(FATAL_ERROR " Missing python header: ${PYTHON_INCLUDE_DIRS}/Python.h")
endif()

View File

@@ -0,0 +1,70 @@
# - Find Fftw3 library
# Find the native Fftw3 includes and library
# This module defines
# FFTW3_INCLUDE_DIRS, where to find fftw3.h, Set when
# FFTW3_INCLUDE_DIR is found.
# FFTW3_LIBRARIES, libraries to link against to use Fftw3.
# FFTW3_ROOT_DIR, The base directory to search for Fftw3.
# This can also be an environment variable.
# FFTW3_FOUND, If false, do not try to use Fftw3.
#
# also defined, but not for general use are
# FFTW3_LIBRARY, where to find the Fftw3 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 FFTW3_ROOT_DIR was defined in the environment, use it.
IF(NOT FFTW3_ROOT_DIR AND NOT $ENV{FFTW3_ROOT_DIR} STREQUAL "")
SET(FFTW3_ROOT_DIR $ENV{FFTW3_ROOT_DIR})
ENDIF()
SET(_fftw3_SEARCH_DIRS
${FFTW3_ROOT_DIR}
/usr/local
/sw # Fink
/opt/local # DarwinPorts
/opt/csw # Blastwave
)
FIND_PATH(FFTW3_INCLUDE_DIR
NAMES
fftw3.h
HINTS
${_fftw3_SEARCH_DIRS}
PATH_SUFFIXES
include
)
FIND_LIBRARY(FFTW3_LIBRARY
NAMES
fftw3
HINTS
${_fftw3_SEARCH_DIRS}
PATH_SUFFIXES
lib64 lib
)
# handle the QUIETLY and REQUIRED arguments and set FFTW3_FOUND to TRUE if
# all listed variables are TRUE
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Fftw3 DEFAULT_MSG
FFTW3_LIBRARY FFTW3_INCLUDE_DIR)
IF(FFTW3_FOUND)
SET(FFTW3_LIBRARIES ${FFTW3_LIBRARY})
SET(FFTW3_INCLUDE_DIRS ${FFTW3_INCLUDE_DIR})
ENDIF(FFTW3_FOUND)
MARK_AS_ADVANCED(
FFTW3_INCLUDE_DIR
FFTW3_LIBRARY
)

View File

@@ -0,0 +1,70 @@
# - Find Jack library
# Find the native Jack includes and library
# This module defines
# JACK_INCLUDE_DIRS, where to find jack.h, Set when
# JACK_INCLUDE_DIR is found.
# JACK_LIBRARIES, libraries to link against to use Jack.
# JACK_ROOT_DIR, The base directory to search for Jack.
# This can also be an environment variable.
# JACK_FOUND, If false, do not try to use Jack.
#
# also defined, but not for general use are
# JACK_LIBRARY, where to find the Jack 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 JACK_ROOT_DIR was defined in the environment, use it.
IF(NOT JACK_ROOT_DIR AND NOT $ENV{JACK_ROOT_DIR} STREQUAL "")
SET(JACK_ROOT_DIR $ENV{JACK_ROOT_DIR})
ENDIF()
SET(_jack_SEARCH_DIRS
${JACK_ROOT_DIR}
/usr/local
/sw # Fink
/opt/local # DarwinPorts
/opt/csw # Blastwave
)
FIND_PATH(JACK_INCLUDE_DIR
NAMES
jack.h
HINTS
${_jack_SEARCH_DIRS}
PATH_SUFFIXES
include/jack
)
FIND_LIBRARY(JACK_LIBRARY
NAMES
jack
HINTS
${_jack_SEARCH_DIRS}
PATH_SUFFIXES
lib64 lib
)
# handle the QUIETLY and REQUIRED arguments and set JACK_FOUND to TRUE if
# all listed variables are TRUE
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Jack DEFAULT_MSG
JACK_LIBRARY JACK_INCLUDE_DIR)
IF(JACK_FOUND)
SET(JACK_LIBRARIES ${JACK_LIBRARY})
SET(JACK_INCLUDE_DIRS ${JACK_INCLUDE_DIR})
ENDIF(JACK_FOUND)
MARK_AS_ADVANCED(
JACK_INCLUDE_DIR
JACK_LIBRARY
)

View File

@@ -0,0 +1,70 @@
# - Find JeMalloc library
# Find the native JeMalloc includes and library
# This module defines
# JEMALLOC_INCLUDE_DIRS, where to find jemalloc.h, Set when
# JEMALLOC_INCLUDE_DIR is found.
# JEMALLOC_LIBRARIES, libraries to link against to use JeMalloc.
# JEMALLOC_ROOT_DIR, The base directory to search for JeMalloc.
# This can also be an environment variable.
# JEMALLOC_FOUND, If false, do not try to use JeMalloc.
#
# also defined, but not for general use are
# JEMALLOC_LIBRARY, where to find the JeMalloc 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 JEMALLOC_ROOT_DIR was defined in the environment, use it.
IF(NOT JEMALLOC_ROOT_DIR AND NOT $ENV{JEMALLOC_ROOT_DIR} STREQUAL "")
SET(JEMALLOC_ROOT_DIR $ENV{JEMALLOC_ROOT_DIR})
ENDIF()
SET(_jemalloc_SEARCH_DIRS
${JEMALLOC_ROOT_DIR}
/usr/local
/sw # Fink
/opt/local # DarwinPorts
/opt/csw # Blastwave
)
FIND_PATH(JEMALLOC_INCLUDE_DIR
NAMES
jemalloc.h
HINTS
${_jemalloc_SEARCH_DIRS}
PATH_SUFFIXES
include/jemalloc
)
FIND_LIBRARY(JEMALLOC_LIBRARY
NAMES
jemalloc
HINTS
${_jemalloc_SEARCH_DIRS}
PATH_SUFFIXES
lib64 lib
)
# handle the QUIETLY and REQUIRED arguments and set JEMALLOC_FOUND to TRUE if
# all listed variables are TRUE
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(JeMalloc DEFAULT_MSG
JEMALLOC_LIBRARY JEMALLOC_INCLUDE_DIR)
IF(JEMALLOC_FOUND)
SET(JEMALLOC_LIBRARIES ${JEMALLOC_LIBRARY})
SET(JEMALLOC_INCLUDE_DIRS ${JEMALLOC_INCLUDE_DIR})
ENDIF(JEMALLOC_FOUND)
MARK_AS_ADVANCED(
JEMALLOC_INCLUDE_DIR
JEMALLOC_LIBRARY
)

View File

@@ -0,0 +1,118 @@
# - Find OpenCOLLADA library
# Find the native OpenCOLLADA includes and library
# This module defines
# OPENCOLLADA_INCLUDE_DIRS, where to find COLLADABaseUtils/ and
# COLLADAFramework/, Set when OPENCOLLADA_INCLUDE_DIR is found.
# OPENCOLLADA_LIBRARIES, libraries to link against to use OpenCOLLADA.
# OPENCOLLADA_ROOT_DIR, The base directory to search for OpenCOLLADA.
# This can also be an environment variable.
# OPENCOLLADA_FOUND, If false, do not try to use OpenCOLLADA.
#
# also defined, but not for general use are
# OPENCOLLADA_LIBRARY, where to find the OpenCOLLADA 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.
#=============================================================================
# note about include paths, there are 2 ways includes are set
#
# Where '/usr/include/opencollada' is the root dir:
# /usr/include/opencollada/COLLADABaseUtils/COLLADABUPlatform.h
#
# Where '/opt/opencollada' is the base dir:
# /opt/opencollada/COLLADABaseUtils/include/COLLADABUPlatform.h
# If OPENCOLLADA_ROOT_DIR was defined in the environment, use it.
IF(NOT OPENCOLLADA_ROOT_DIR AND NOT $ENV{OPENCOLLADA_ROOT_DIR} STREQUAL "")
SET(OPENCOLLADA_ROOT_DIR $ENV{OPENCOLLADA_ROOT_DIR})
ENDIF()
SET(_opencollada_FIND_INCLUDES
COLLADAStreamWriter
COLLADABaseUtils
COLLADAFramework
COLLADASaxFrameworkLoader
GeneratedSaxParser
)
SET(_opencollada_FIND_COMPONENTS
OpenCOLLADAStreamWriter
OpenCOLLADASaxFrameworkLoader
OpenCOLLADAFramework
OpenCOLLADABaseUtils
GeneratedSaxParser
UTF
MathMLSolver
pcre
ftoa
buffer
xml2
)
SET(_opencollada_SEARCH_DIRS
${OPENCOLLADA_ROOT_DIR}
/usr/local
/sw # Fink
/opt/local # DarwinPorts
/opt/csw # Blastwave
)
SET(_opencollada_INCLUDES)
FOREACH(COMPONENT ${_opencollada_FIND_INCLUDES})
STRING(TOUPPER ${COMPONENT} UPPERCOMPONENT)
# need to use this even thouh we are looking for a dir
FIND_FILE(OPENCOLLADA_${UPPERCOMPONENT}_INCLUDE_DIR
NAMES
${COMPONENT}/include
${COMPONENT}
# Ubuntu ppa needs this.
# Alternative would be to suffix all members of search path
# but this is less trouble, just looks strange.
include/opencollada/${COMPONENT}
HINTS
${_opencollada_SEARCH_DIRS}
)
MARK_AS_ADVANCED(OPENCOLLADA_${UPPERCOMPONENT}_INCLUDE_DIR)
LIST(APPEND _opencollada_INCLUDES "${OPENCOLLADA_${UPPERCOMPONENT}_INCLUDE_DIR}")
ENDFOREACH()
SET(_opencollada_LIBRARIES)
FOREACH(COMPONENT ${_opencollada_FIND_COMPONENTS})
STRING(TOUPPER ${COMPONENT} UPPERCOMPONENT)
FIND_LIBRARY(OPENCOLLADA_${UPPERCOMPONENT}_LIBRARY
NAMES
${COMPONENT}
HINTS
${_opencollada_SEARCH_DIRS}
PATH_SUFFIXES
lib64 lib
# Ubuntu ppa needs this.
lib64/opencollada lib/opencollada
)
MARK_AS_ADVANCED(OPENCOLLADA_${UPPERCOMPONENT}_LIBRARY)
LIST(APPEND _opencollada_LIBRARIES "${OPENCOLLADA_${UPPERCOMPONENT}_LIBRARY}")
ENDFOREACH()
# handle the QUIETLY and REQUIRED arguments and set OPENCOLLADA_FOUND to TRUE if
# all listed variables are TRUE
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(OpenCOLLADA DEFAULT_MSG
_opencollada_LIBRARIES _opencollada_INCLUDES)
IF(OPENCOLLADA_FOUND)
SET(OPENCOLLADA_LIBRARIES ${_opencollada_LIBRARIES})
SET(OPENCOLLADA_INCLUDE_DIRS ${_opencollada_INCLUDES})
ENDIF(OPENCOLLADA_FOUND)

View File

@@ -0,0 +1,92 @@
# - Find OpenEXR library
# Find the native OpenEXR includes and library
# This module defines
# OPENEXR_INCLUDE_DIRS, where to find ImfXdr.h, etc. Set when
# OPENEXR_INCLUDE_DIR is found.
# OPENEXR_LIBRARIES, libraries to link against to use OpenEXR.
# OPENEXR_ROOT_DIR, The base directory to search for OpenEXR.
# This can also be an environment variable.
# OPENEXR_FOUND, If false, do not try to use OpenEXR.
#
# For indervidual library access these advanced settings are available
# OPENEXR_HALF_LIBRARY, Path to Half library
# OPENEXR_IEX_LIBRARY, Path to Half library
# OPENEXR_ILMIMF_LIBRARY, Path to Ilmimf library
# OPENEXR_ILMTHREAD_LIBRARY, Path to IlmThread library
# OPENEXR_IMATH_LIBRARY, Path to Imath library
#
# also defined, but not for general use are
# OPENEXR_LIBRARY, where to find the OpenEXR 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 OPENEXR_ROOT_DIR was defined in the environment, use it.
IF(NOT OPENEXR_ROOT_DIR AND NOT $ENV{OPENEXR_ROOT_DIR} STREQUAL "")
SET(OPENEXR_ROOT_DIR $ENV{OPENEXR_ROOT_DIR})
ENDIF()
SET(_openexr_FIND_COMPONENTS
Half
Iex
IlmImf
IlmThread
Imath
)
SET(_openexr_SEARCH_DIRS
${OPENEXR_ROOT_DIR}
/usr/local
/sw # Fink
/opt/local # DarwinPorts
/opt/csw # Blastwave
)
FIND_PATH(OPENEXR_INCLUDE_DIR
NAMES
ImfXdr.h
HINTS
${_openexr_SEARCH_DIRS}
PATH_SUFFIXES
include/OpenEXR
)
SET(_openexr_LIBRARIES)
FOREACH(COMPONENT ${_openexr_FIND_COMPONENTS})
STRING(TOUPPER ${COMPONENT} UPPERCOMPONENT)
FIND_LIBRARY(OPENEXR_${UPPERCOMPONENT}_LIBRARY
NAMES
${COMPONENT}
HINTS
${_openexr_SEARCH_DIRS}
PATH_SUFFIXES
lib64 lib
)
LIST(APPEND _openexr_LIBRARIES "${OPENEXR_${UPPERCOMPONENT}_LIBRARY}")
ENDFOREACH()
# handle the QUIETLY and REQUIRED arguments and set OPENEXR_FOUND to TRUE if
# all listed variables are TRUE
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(OpenEXR DEFAULT_MSG
_openexr_LIBRARIES OPENEXR_INCLUDE_DIR)
IF(OPENEXR_FOUND)
SET(OPENEXR_LIBRARIES ${_openexr_LIBRARIES})
SET(OPENEXR_INCLUDE_DIRS ${OPENEXR_INCLUDE_DIR})
ENDIF()
MARK_AS_ADVANCED(OPENEXR_INCLUDE_DIR)
FOREACH(COMPONENT ${_openexr_FIND_COMPONENTS})
STRING(TOUPPER ${COMPONENT} UPPERCOMPONENT)
MARK_AS_ADVANCED(OPENEXR_${UPPERCOMPONENT}_LIBRARY)
ENDFOREACH()

View File

@@ -0,0 +1,70 @@
# - Find OpenJPEG library
# Find the native OpenJPEG includes and library
# This module defines
# OPENJPEG_INCLUDE_DIRS, where to find openjpeg.h, Set when
# OPENJPEG_INCLUDE_DIR is found.
# OPENJPEG_LIBRARIES, libraries to link against to use OpenJPEG.
# OPENJPEG_ROOT_DIR, The base directory to search for OpenJPEG.
# This can also be an environment variable.
# OPENJPEG_FOUND, If false, do not try to use OpenJPEG.
#
# also defined, but not for general use are
# OPENJPEG_LIBRARY, where to find the OpenJPEG 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 OPENJPEG_ROOT_DIR was defined in the environment, use it.
IF(NOT OPENJPEG_ROOT_DIR AND NOT $ENV{OPENJPEG_ROOT_DIR} STREQUAL "")
SET(OPENJPEG_ROOT_DIR $ENV{OPENJPEG_ROOT_DIR})
ENDIF()
SET(_openjpeg_SEARCH_DIRS
${OPENJPEG_ROOT_DIR}
/usr/local
/sw # Fink
/opt/local # DarwinPorts
/opt/csw # Blastwave
)
FIND_PATH(OPENJPEG_INCLUDE_DIR
NAMES
openjpeg.h
HINTS
${_openjpeg_SEARCH_DIRS}
PATH_SUFFIXES
include
)
FIND_LIBRARY(OPENJPEG_LIBRARY
NAMES
openjpeg
HINTS
${_openjpeg_SEARCH_DIRS}
PATH_SUFFIXES
lib64 lib
)
# handle the QUIETLY and REQUIRED arguments and set OPENJPEG_FOUND to TRUE if
# all listed variables are TRUE
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(OpenJPEG DEFAULT_MSG
OPENJPEG_LIBRARY OPENJPEG_INCLUDE_DIR)
IF(OPENJPEG_FOUND)
SET(OPENJPEG_LIBRARIES ${OPENJPEG_LIBRARY})
SET(OPENJPEG_INCLUDE_DIRS ${OPENJPEG_INCLUDE_DIR})
ENDIF(OPENJPEG_FOUND)
MARK_AS_ADVANCED(
OPENJPEG_INCLUDE_DIR
OPENJPEG_LIBRARY
)

View File

@@ -0,0 +1,121 @@
# - Find Python libraries
# Find the native Python includes and library
#
# Note:, This is not _yet_ intended to be a general python module for other
# projects to use since its hard coded to python 3.2 as blender only supports
# a single python version.
# This is for blender/unix python only.
#
# This module defines
# PYTHON_VERSION
# PYTHON_INCLUDE_DIRS
# PYTHON_LIBRARIES
# PYTHON_LIBPATH, Used for installation
# PYTHON_LINKFLAGS
# PYTHON_ROOT_DIR, The base directory to search for Python.
# This can also be an environment variable.
#
# also defined, but not for general use are
# PYTHON_LIBRARY, where to find the python 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 PYTHON_ROOT_DIR was defined in the environment, use it.
IF(NOT PYTHON_ROOT_DIR AND NOT $ENV{PYTHON_ROOT_DIR} STREQUAL "")
SET(PYTHON_ROOT_DIR $ENV{PYTHON_ROOT_DIR})
ENDIF()
IF(DEFINED PYTHON_VERSION)
SET(PYTHON_VERSION "${PYTHON_VERSION}" CACHE STRING "")
ELSE()
SET(PYTHON_VERSION 3.2 CACHE STRING "")
ENDIF()
MARK_AS_ADVANCED(PYTHON_VERSION)
SET(PYTHON_LINKFLAGS "-Xlinker -export-dynamic")
MARK_AS_ADVANCED(PYTHON_LINKFLAGS)
SET(_python_ABI_FLAGS
"m;mu;u; " # release
"md;mud;ud;d" # debug
)
STRING(REPLACE "." "" _PYTHON_VERSION_NO_DOTS ${PYTHON_VERSION})
SET(_python_SEARCH_DIRS
${PYTHON_ROOT_DIR}
"$ENV{HOME}/py${_PYTHON_VERSION_NO_DOTS}"
"/opt/py${_PYTHON_VERSION_NO_DOTS}"
)
FOREACH(_CURRENT_ABI_FLAGS ${_python_ABI_FLAGS})
#IF(CMAKE_BUILD_TYPE STREQUAL Debug)
# SET(_CURRENT_ABI_FLAGS "d${_CURRENT_ABI_FLAGS}")
#ENDIF()
STRING(REPLACE " " "" _CURRENT_ABI_FLAGS ${_CURRENT_ABI_FLAGS})
FIND_PATH(PYTHON_INCLUDE_DIR
NAMES
Python.h
HINTS
${_python_SEARCH_DIRS}
PATH_SUFFIXES
include/python${PYTHON_VERSION}${_CURRENT_ABI_FLAGS}
)
FIND_LIBRARY(PYTHON_LIBRARY
NAMES
"python${PYTHON_VERSION}${_CURRENT_ABI_FLAGS}"
HINTS
${_python_SEARCH_DIRS}
PATH_SUFFIXES
lib64 lib
)
IF(PYTHON_LIBRARY AND PYTHON_INCLUDE_DIR)
break()
ELSE()
# ensure we dont find values from 2 different ABI versions
UNSET(PYTHON_INCLUDE_DIR CACHE)
UNSET(PYTHON_LIBRARY CACHE)
ENDIF()
ENDFOREACH()
UNSET(_CURRENT_ABI_FLAGS)
UNSET(_CURRENT_PATH)
UNSET(_python_ABI_FLAGS)
UNSET(_python_SEARCH_DIRS)
# handle the QUIETLY and REQUIRED arguments and SET PYTHONLIBSUNIX_FOUND to TRUE IF
# all listed variables are TRUE
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(PythonLibsUnix DEFAULT_MSG
PYTHON_LIBRARY PYTHON_INCLUDE_DIR)
IF(PYTHONLIBSUNIX_FOUND)
# Assign cache items
SET(PYTHON_INCLUDE_DIRS ${PYTHON_INCLUDE_DIR})
SET(PYTHON_LIBRARIES ${PYTHON_LIBRARY})
# we need this for installation
GET_FILENAME_COMPONENT(PYTHON_LIBPATH ${PYTHON_LIBRARY} PATH)
# not used
# SET(PYTHON_BINARY ${PYTHON_EXECUTABLE} CACHE STRING "")
MARK_AS_ADVANCED(
PYTHON_INCLUDE_DIR
PYTHON_LIBRARY
)
ENDIF()

View File

@@ -0,0 +1,70 @@
# - Find Samplerate library
# Find the native Samplerate includes and library
# This module defines
# SAMPLERATE_INCLUDE_DIRS, where to find samplerate.h, Set when
# SAMPLERATE_INCLUDE_DIR is found.
# SAMPLERATE_LIBRARIES, libraries to link against to use Samplerate.
# SAMPLERATE_ROOT_DIR, The base directory to search for Samplerate.
# This can also be an environment variable.
# SAMPLERATE_FOUND, If false, do not try to use Samplerate.
#
# also defined, but not for general use are
# SAMPLERATE_LIBRARY, where to find the Samplerate 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 SAMPLERATE_ROOT_DIR was defined in the environment, use it.
IF(NOT SAMPLERATE_ROOT_DIR AND NOT $ENV{SAMPLERATE_ROOT_DIR} STREQUAL "")
SET(SAMPLERATE_ROOT_DIR $ENV{SAMPLERATE_ROOT_DIR})
ENDIF()
SET(_samplerate_SEARCH_DIRS
${SAMPLERATE_ROOT_DIR}
/usr/local
/sw # Fink
/opt/local # DarwinPorts
/opt/csw # Blastwave
)
FIND_PATH(SAMPLERATE_INCLUDE_DIR
NAMES
samplerate.h
HINTS
${_samplerate_SEARCH_DIRS}
PATH_SUFFIXES
include
)
FIND_LIBRARY(SAMPLERATE_LIBRARY
NAMES
samplerate
HINTS
${_samplerate_SEARCH_DIRS}
PATH_SUFFIXES
lib64 lib
)
# handle the QUIETLY and REQUIRED arguments and set SAMPLERATE_FOUND to TRUE if
# all listed variables are TRUE
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Samplerate DEFAULT_MSG
SAMPLERATE_LIBRARY SAMPLERATE_INCLUDE_DIR)
IF(SAMPLERATE_FOUND)
SET(SAMPLERATE_LIBRARIES ${SAMPLERATE_LIBRARY})
SET(SAMPLERATE_INCLUDE_DIRS ${SAMPLERATE_INCLUDE_DIR})
ENDIF(SAMPLERATE_FOUND)
MARK_AS_ADVANCED(
SAMPLERATE_INCLUDE_DIR
SAMPLERATE_LIBRARY
)

View File

@@ -0,0 +1,68 @@
# - Find SndFile library
# Find the native SndFile includes and library
# This module defines
# SNDFILE_INCLUDE_DIRS, where to find sndfile.h, Set when
# SNDFILE_INCLUDE_DIR is found.
# SNDFILE_LIBRARIES, libraries to link against to use SndFile.
# SNDFILE_ROOT_DIR, The base directory to search for SndFile.
# This can also be an environment variable.
# SNDFILE_FOUND, If false, do not try to use SndFile.
#
# also defined, but not for general use are
# SNDFILE_LIBRARY, where to find the SndFile 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 SNDFILE_ROOT_DIR was defined in the environment, use it.
IF(NOT SNDFILE_ROOT_DIR AND NOT $ENV{SNDFILE_ROOT_DIR} STREQUAL "")
SET(SNDFILE_ROOT_DIR $ENV{SNDFILE_ROOT_DIR})
ENDIF()
SET(_sndfile_SEARCH_DIRS
${SNDFILE_ROOT_DIR}
/usr/local
/sw # Fink
/opt/local # DarwinPorts
/opt/csw # Blastwave
)
FIND_PATH(SNDFILE_INCLUDE_DIR sndfile.h
HINTS
${_sndfile_SEARCH_DIRS}
PATH_SUFFIXES
include
)
FIND_LIBRARY(SNDFILE_LIBRARY
NAMES
sndfile
HINTS
${_sndfile_SEARCH_DIRS}
PATH_SUFFIXES
lib64 lib
)
# handle the QUIETLY and REQUIRED arguments and set SNDFILE_FOUND to TRUE if
# all listed variables are TRUE
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(SndFile DEFAULT_MSG
SNDFILE_LIBRARY SNDFILE_INCLUDE_DIR)
IF(SNDFILE_FOUND)
SET(SNDFILE_LIBRARIES ${SNDFILE_LIBRARY})
SET(SNDFILE_INCLUDE_DIRS ${SNDFILE_INCLUDE_DIR})
ENDIF(SNDFILE_FOUND)
MARK_AS_ADVANCED(
SNDFILE_INCLUDE_DIR
SNDFILE_LIBRARY
)

View 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
)

View File

@@ -27,9 +27,9 @@ endif()
# Write a file with the SVNVERSION define
file(WRITE buildinfo.h.txt
"#define BUILD_REV ${MY_WC_REVISION}\n"
"#define BUILD_DATE ${BUILD_DATE}\n"
"#define BUILD_TIME ${BUILD_TIME}\n"
"#define BUILD_REV \"${MY_WC_REVISION}\"\n"
"#define BUILD_DATE \"${BUILD_DATE}\"\n"
"#define BUILD_TIME \"${BUILD_TIME}\"\n"
)
# Copy the file to the final header only if the version changes

View File

@@ -23,27 +23,31 @@
# <pep8 compliant>
IGNORE = \
"/test/",\
"/decimate_glut_test/",\
"/BSP_GhostTest/",\
"/release/",\
"/xembed/",\
"/decimation/intern/future/",\
"/TerraplayNetwork/",\
"/ik_glut_test/"
from cmake_consistency_check_config import IGNORE, UTF8_CHECK, SOURCE_DIR
import os
from os.path import join, dirname, normpath, abspath, splitext
from os.path import join, dirname, normpath, splitext
base = join(os.path.dirname(__file__), "..", "..")
base = normpath(base)
base = abspath(base)
print("Scanning:", base)
print("Scanning:", SOURCE_DIR)
global_h = set()
global_c = set()
global_refs = {}
def replace_line(f, i, text, keep_indent=True):
file_handle = open(f, 'r')
data = file_handle.readlines()
file_handle.close()
l = data[i]
ws = l[:len(l) - len(l.lstrip())]
data[i] = "%s%s\n" % (ws, text)
file_handle = open(f, 'w')
file_handle.writelines(data)
file_handle.close()
def source_list(path, filename_check=None):
@@ -88,7 +92,20 @@ def cmake_get_src(f):
found = False
i = 0
# print(f)
def is_definition(l, f, i, name):
if ('set(%s' % name) in l or ('set(' in l and l.endswith(name)):
if len(l.split()) > 1:
raise Exception("strict formatting not kept 'set(%s*' %s:%d" % (name, f, i))
return True
if ("list(APPEND %s" % name) in l or ('list(APPEND ' in l and l.endswith(name)):
if l.endswith(")"):
raise Exception("strict formatting not kept 'list(APPEND %s...)' on 1 line %s:%d" % (name, f, i))
return True
while it is not None:
context_name = ""
while it is not None:
i += 1
try:
@@ -98,16 +115,13 @@ def cmake_get_src(f):
break
l = l.strip()
if not l.startswith("#"):
if 'set(SRC' in l or ('set(' in l and l.endswith("SRC")):
if len(l.split()) > 1:
raise Exception("strict formatting not kept 'set(SRC*' %s:%d" % (f, i))
found = True
found = is_definition(l, f, i, "SRC")
if found:
context_name = "SRC"
break
if "list(APPEND SRC" in l:
if l.endswith(")"):
raise Exception("strict formatting not kept 'list(APPEND SRC...)' on 1 line %s:%d" % (f, i))
found = True
found = is_definition(l, f, i, "INC")
if found:
context_name = "INC"
break
if found:
@@ -136,21 +150,44 @@ def cmake_get_src(f):
if not l:
pass
elif l.startswith("$"):
print("Cant use var '%s' %s:%d" % (l, f, i))
if context_name == "SRC":
# assume if it ends with context_name we know about it
if not l.split("}")[0].endswith(context_name):
print("Can't use var '%s' %s:%d" % (l, f, i))
elif len(l.split()) > 1:
raise Exception("Multi-line define '%s' %s:%d" % (l, f, i))
else:
new_file = normpath(join(cmake_base, l))
if is_c_header(new_file):
sources_h.append(new_file)
elif is_c(new_file):
sources_c.append(new_file)
elif l in ("PARENT_SCOPE", ):
# cmake var, ignore
pass
else:
raise Exception("unknown file type - not c or h %s -> %s" % (f, new_file))
if context_name == "SRC":
if is_c_header(new_file):
sources_h.append(new_file)
global_refs.setdefault(new_file, []).append((f, i))
elif is_c(new_file):
sources_c.append(new_file)
global_refs.setdefault(new_file, []).append((f, i))
elif l in ("PARENT_SCOPE", ):
# cmake var, ignore
pass
elif new_file.endswith(".list"):
pass
elif new_file.endswith(".def"):
pass
else:
raise Exception("unknown file type - not c or h %s -> %s" % (f, new_file))
elif context_name == "INC":
if os.path.isdir(new_file):
new_path_rel = os.path.relpath(new_file, cmake_base)
if new_path_rel != l:
print("overly relative path:\n %s:%d\n %s\n %s" % (f, i, l, new_path_rel))
## Save time. just replace the line
# replace_line(f, i - 1, new_path_rel)
else:
raise Exception("non existant include %s:%d -> %s" % (f, i, new_file))
# print(new_file)
@@ -170,10 +207,14 @@ def cmake_get_src(f):
print(" missing: " + ff)
'''
# reset
sources_h[:] = []
sources_c[:] = []
filen.close()
for cmake in source_list(base, is_cmake):
for cmake in source_list(SOURCE_DIR, is_cmake):
cmake_get_src(cmake)
@@ -183,39 +224,74 @@ def is_ignore(f):
return True
return False
# First do stupid check, do these files exist?
print("\nChecking for missing references:")
is_err = False
errs = []
for f in (global_h | global_c):
if f.endswith("dna.c"):
continue
if not os.path.exists(f):
raise Exception("CMake referenced file missing: " + f)
refs = global_refs[f]
if refs:
for cf, i in refs:
errs.append((cf, i))
else:
raise Exception("CMake referenecs missing, internal error, aborting!")
is_err = True
errs.sort()
errs.reverse()
for cf, i in errs:
print("%s:%d" % (cf, i))
# Write a 'sed' script, useful if we get a lot of these
# print("sed '%dd' '%s' > '%s.tmp' ; mv '%s.tmp' '%s'" % (i, cf, cf, cf, cf))
if is_err:
raise Exception("CMake referenecs missing files, aborting!")
del is_err
del errs
# now check on files not accounted for.
print("\nC/C++ Files CMake doesnt know about...")
for cf in sorted(source_list(base, is_c)):
for cf in sorted(source_list(SOURCE_DIR, is_c)):
if not is_ignore(cf):
if cf not in global_c:
print("missing_c: ", cf)
# check if automake builds a corrasponding .o file.
'''
if cf in global_c:
out1 = os.path.splitext(cf)[0] + ".o"
out2 = os.path.splitext(cf)[0] + ".Po"
out2_dir, out2_file = out2 = os.path.split(out2)
out2 = os.path.join(out2_dir, ".deps", out2_file)
if not os.path.exists(out1) and not os.path.exists(out2):
print("bad_c: ", cf)
'''
print("\nC/C++ Headers CMake doesnt know about...")
for hf in sorted(source_list(base, is_c_header)):
for hf in sorted(source_list(SOURCE_DIR, is_c_header)):
if not is_ignore(hf):
if hf not in global_h:
print("missing_h: ", hf)
# test encoding
import traceback
for files in (global_c, global_h):
for f in sorted(files):
if os.path.exists(f):
# ignore outside of our source tree
if "extern" not in f:
i = 1
try:
for l in open(f, "r", encoding="utf8"):
i += 1
except:
print("Non utf8: %s:%d" % (f, i))
if i > 1:
traceback.print_exc()
if UTF8_CHECK:
# test encoding
import traceback
for files in (global_c, global_h):
for f in sorted(files):
if os.path.exists(f):
# ignore outside of our source tree
if "extern" not in f:
i = 1
try:
for l in open(f, "r", encoding="utf8"):
i += 1
except:
print("Non utf8: %s:%d" % (f, i))
if i > 1:
traceback.print_exc()

View File

@@ -0,0 +1,48 @@
import os
IGNORE = (
"/test/",
"/decimate_glut_test/",
"/BSP_GhostTest/",
"/release/",
"/xembed/",
"/decimation/intern/future/",
"/TerraplayNetwork/",
"/ik_glut_test/",
# specific source files
"extern/Eigen2/Eigen/src/Cholesky/CholeskyInstantiations.cpp",
"extern/Eigen2/Eigen/src/Core/CoreInstantiations.cpp",
"extern/Eigen2/Eigen/src/QR/QrInstantiations.cpp",
"extern/bullet2/src/BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.cpp",
"extern/bullet2/src/BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.cpp",
"extern/bullet2/src/BulletCollision/CollisionDispatch/btInternalEdgeUtility.cpp",
"extern/bullet2/src/BulletCollision/CollisionShapes/btBox2dShape.cpp",
"extern/bullet2/src/BulletCollision/CollisionShapes/btConvex2dShape.cpp",
"extern/bullet2/src/BulletDynamics/Character/btKinematicCharacterController.cpp",
"extern/bullet2/src/BulletDynamics/ConstraintSolver/btHinge2Constraint.cpp",
"extern/bullet2/src/BulletDynamics/ConstraintSolver/btUniversalConstraint.cpp",
"extern/eltopo/common/meshes/ObjLoader.cpp",
"extern/eltopo/common/meshes/meshloader.cpp",
"extern/eltopo/common/openglutils.cpp",
"extern/eltopo/eltopo3d/broadphase_blenderbvh.cpp",
"source/blender/imbuf/intern/imbuf_cocoa.m",
"extern/bullet2/src/BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.h",
"extern/bullet2/src/BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.h",
"extern/bullet2/src/BulletCollision/CollisionDispatch/btInternalEdgeUtility.h",
"extern/bullet2/src/BulletCollision/CollisionShapes/btBox2dShape.h",
"extern/bullet2/src/BulletCollision/CollisionShapes/btConvex2dShape.h",
"extern/bullet2/src/BulletDynamics/Character/btKinematicCharacterController.h",
"extern/bullet2/src/BulletDynamics/ConstraintSolver/btHinge2Constraint.h",
"extern/bullet2/src/BulletDynamics/ConstraintSolver/btUniversalConstraint.h",
"extern/eltopo/common/meshes/Edge.hpp",
"extern/eltopo/common/meshes/ObjLoader.hpp",
"extern/eltopo/common/meshes/TriangleIndex.hpp",
"extern/eltopo/common/meshes/meshloader.h",
"extern/eltopo/eltopo3d/broadphase_blenderbvh.h"
)
UTF8_CHECK = True
SOURCE_DIR = os.path.normpath(os.path.abspath(os.path.normpath(os.path.join(os.path.dirname(__file__), "..", ".."))))

View File

@@ -30,7 +30,18 @@ Example linux usage
Windows not supported so far
"""
from project_info import *
from project_info import (SIMPLE_PROJECTFILE,
SOURCE_DIR,
CMAKE_DIR,
PROJECT_DIR,
source_list,
is_project_file,
is_c_header,
# is_py,
cmake_advanced_info,
cmake_compiler_defines,
)
import os
from os.path import join, dirname, normpath, relpath, exists

View File

@@ -31,7 +31,17 @@ example linux usage
python .~/blenderSVN/blender/build_files/cmake/cmake_qtcreator_project.py ~/blenderSVN/cmake
"""
from project_info import *
from project_info import (SIMPLE_PROJECTFILE,
SOURCE_DIR,
# CMAKE_DIR,
PROJECT_DIR,
source_list,
is_project_file,
is_c_header,
is_py,
cmake_advanced_info,
cmake_compiler_defines,
)
import os
import sys

View File

@@ -0,0 +1,24 @@
# headless configuration, useful in for servers or renderfarms
# builds without a windowing system (X11/Windows/Cocoa).
#
# Example usage:
# cmake -C../blender/build_files/cmake/config/blender_headless.cmake ../blender
#
set(WITH_HEADLESS ON CACHE FORCE BOOL)
set(WITH_GAMEENGINE OFF CACHE FORCE BOOL)
# disable audio, its possible some devs may want this but for now disable
# so the python module doesnt hold the audio device and loads quickly.
set(WITH_AUDASPACE OFF CACHE FORCE BOOL)
set(WITH_SAMPLERATE OFF CACHE FORCE BOOL)
set(WITH_FFTW3 OFF CACHE FORCE BOOL)
set(WITH_JACK OFF CACHE FORCE BOOL)
set(WITH_SDL OFF CACHE FORCE BOOL)
set(WITH_OPENAL OFF CACHE FORCE BOOL)
set(WITH_CODEC_FFMPEG OFF CACHE FORCE BOOL)
set(WITH_CODEC_SNDFILE OFF CACHE FORCE BOOL)
# other features which are not especially useful as a python module
set(WITH_X11_XINPUT OFF CACHE FORCE BOOL)
set(WITH_INPUT_NDOF OFF CACHE FORCE BOOL)

View File

@@ -0,0 +1,43 @@
# turn everything OFF except for python which defaults to ON
# and is needed for the UI
#
# Example usage:
# cmake -C../blender/build_files/cmake/config/blender_lite.cmake ../blender
#
set(WITH_INSTALL_PORTABLE ON CACHE FORCE BOOL)
set(WITH_BUILDINFO OFF CACHE FORCE BOOL)
set(WITH_BUILTIN_GLEW OFF CACHE FORCE BOOL)
set(WITH_BULLET OFF CACHE FORCE BOOL)
set(WITH_CODEC_FFMPEG OFF CACHE FORCE BOOL)
set(WITH_CODEC_SNDFILE OFF CACHE FORCE BOOL)
set(WITH_FFTW3 OFF CACHE FORCE BOOL)
set(WITH_GAMEENGINE OFF CACHE FORCE BOOL)
set(WITH_IK_ITASC OFF CACHE FORCE BOOL)
set(WITH_IMAGE_CINEON OFF CACHE FORCE BOOL)
set(WITH_IMAGE_DDS OFF CACHE FORCE BOOL)
set(WITH_IMAGE_FRAMESERVER OFF CACHE FORCE BOOL)
set(WITH_IMAGE_HDR OFF CACHE FORCE BOOL)
set(WITH_IMAGE_OPENEXR OFF CACHE FORCE BOOL)
set(WITH_IMAGE_OPENJPEG OFF CACHE FORCE BOOL)
set(WITH_IMAGE_REDCODE OFF CACHE FORCE BOOL)
set(WITH_IMAGE_TIFF OFF CACHE FORCE BOOL)
set(WITH_INPUT_NDOF OFF CACHE FORCE BOOL)
set(WITH_INTERNATIONAL OFF CACHE FORCE BOOL)
set(WITH_JACK OFF CACHE FORCE BOOL)
set(WITH_LZMA OFF CACHE FORCE BOOL)
set(WITH_LZO OFF CACHE FORCE BOOL)
set(WITH_MOD_BOOLEAN OFF CACHE FORCE BOOL)
set(WITH_MOD_DECIMATE OFF CACHE FORCE BOOL)
set(WITH_MOD_FLUID OFF CACHE FORCE BOOL)
set(WITH_MOD_SMOKE OFF CACHE FORCE BOOL)
set(WITH_AUDASPACE OFF CACHE FORCE BOOL)
set(WITH_OPENAL OFF CACHE FORCE BOOL)
set(WITH_OPENCOLLADA OFF CACHE FORCE BOOL)
set(WITH_OPENMP OFF CACHE FORCE BOOL)
set(WITH_PYTHON_INSTALL OFF CACHE FORCE BOOL)
set(WITH_RAYOPTIMIZATION OFF CACHE FORCE BOOL)
set(WITH_SAMPLERATE OFF CACHE FORCE BOOL)
set(WITH_SDL OFF CACHE FORCE BOOL)
set(WITH_X11_XINPUT OFF CACHE FORCE BOOL)

View File

@@ -0,0 +1,34 @@
# defaults for building blender as a python module 'bpy'
#
# Example usage:
# cmake -C../blender/build_files/cmake/config/bpy_module.cmake ../blender
#
set(WITH_PYTHON_MODULE ON CACHE FORCE BOOL)
# install into the systems python dir
set(WITH_INSTALL_PORTABLE OFF CACHE FORCE BOOL)
# no point int copying python into python
set(WITH_PYTHON_INSTALL OFF CACHE FORCE BOOL)
# dont build the game engine
set(WITH_GAMEENGINE OFF CACHE FORCE BOOL)
# disable audio, its possible some devs may want this but for now disable
# so the python module doesnt hold the audio device and loads quickly.
set(WITH_AUDASPACE OFF CACHE FORCE BOOL)
set(WITH_SAMPLERATE OFF CACHE FORCE BOOL)
set(WITH_FFTW3 OFF CACHE FORCE BOOL)
set(WITH_JACK OFF CACHE FORCE BOOL)
set(WITH_SDL OFF CACHE FORCE BOOL)
set(WITH_OPENAL OFF CACHE FORCE BOOL)
set(WITH_CODEC_FFMPEG OFF CACHE FORCE BOOL)
set(WITH_CODEC_SNDFILE OFF CACHE FORCE BOOL)
# other features which are not especially useful as a python module
set(WITH_X11_XINPUT OFF CACHE FORCE BOOL)
set(WITH_INPUT_NDOF OFF CACHE FORCE BOOL)
set(WITH_OPENCOLLADA OFF CACHE FORCE BOOL)
set(WITH_INTERNATIONAL OFF CACHE FORCE BOOL)
set(WITH_BULLET OFF CACHE FORCE BOOL)

View File

@@ -17,7 +17,7 @@ cd ~/blender-svn/build-cmake
# cmake without copying files for fast rebuilds
# the files from svn will be used in place
cmake ../blender -DWITH_INSTALL:BOOL=FALSE
cmake ../blender
# make blender, will take some time
make

View File

@@ -1,26 +1,92 @@
# -*- mode: cmake; indent-tabs-mode: t; -*-
# $Id$
# foo_bar.spam --> foo_barMySuffix.spam
macro(file_suffix
file_name_new file_name file_suffix
)
get_filename_component(_file_name_PATH ${file_name} PATH)
get_filename_component(_file_name_NAME_WE ${file_name} NAME_WE)
get_filename_component(_file_name_EXT ${file_name} EXT)
set(${file_name_new} "${_file_name_PATH}/${_file_name_NAME_WE}${file_suffix}${_file_name_EXT}")
unset(_file_name_PATH)
unset(_file_name_NAME_WE)
unset(_file_name_EXT)
endmacro()
# usefil for adding debug suffix to library lists:
# /somepath/foo.lib --> /somepath/foo_d.lib
macro(file_list_suffix
fp_list_new fp_list fn_suffix
)
# incase of empty list
set(_fp)
set(_fp_suffixed)
set(fp_list_new)
foreach(_fp ${fp_list})
file_suffix(_fp_suffixed "${_fp}" "${fn_suffix}")
list(APPEND "${fp_list_new}" "${_fp_suffixed}")
endforeach()
unset(_fp)
unset(_fp_suffixed)
endmacro()
macro(target_link_libraries_optimized TARGET LIBS)
foreach(_LIB ${LIBS})
target_link_libraries(${TARGET} optimized "${_LIB}")
endforeach()
unset(_LIB)
endmacro()
macro(target_link_libraries_debug TARGET LIBS)
foreach(_LIB ${LIBS})
target_link_libraries(${TARGET} debug "${_LIB}")
endforeach()
unset(_LIB)
endmacro()
# Nicer makefiles with -I/1/foo/ instead of -I/1/2/3/../../foo/
# use it instead of include_directories()
macro(blender_include_dirs
includes)
foreach(inc ${ARGV})
get_filename_component(abs_inc ${inc} ABSOLUTE)
list(APPEND all_incs ${abs_inc})
set(_ALL_INCS "")
foreach(_INC ${ARGV})
get_filename_component(_ABS_INC ${_INC} ABSOLUTE)
list(APPEND _ALL_INCS ${_ABS_INC})
# for checking for invalid includes, disable for regular use
##if(NOT EXISTS "${_ABS_INC}/")
## message(FATAL_ERROR "Include not found: ${_ABS_INC}/")
##endif()
endforeach()
include_directories(${all_incs})
include_directories(${_ALL_INCS})
unset(_INC)
unset(_ABS_INC)
unset(_ALL_INCS)
endmacro()
macro(blender_include_dirs_sys
includes)
foreach(inc ${ARGV})
get_filename_component(abs_inc ${inc} ABSOLUTE)
list(APPEND all_incs ${abs_inc})
set(_ALL_INCS "")
foreach(_INC ${ARGV})
get_filename_component(_ABS_INC ${_INC} ABSOLUTE)
list(APPEND _ALL_INCS ${_ABS_INC})
##if(NOT EXISTS "${_ABS_INC}/")
## message(FATAL_ERROR "Include not found: ${_ABS_INC}/")
##endif()
endforeach()
include_directories(SYSTEM ${all_incs})
include_directories(SYSTEM ${_ALL_INCS})
unset(_INC)
unset(_ABS_INC)
unset(_ALL_INCS)
endmacro()
macro(blender_source_group
@@ -29,14 +95,17 @@ macro(blender_source_group
# Group by location on disk
source_group("Source Files" FILES CMakeLists.txt)
foreach(SRC ${sources})
get_filename_component(SRC_EXT ${SRC} EXT)
if(${SRC_EXT} MATCHES ".h" OR ${SRC_EXT} MATCHES ".hpp")
source_group("Header Files" FILES ${SRC})
foreach(_SRC ${sources})
get_filename_component(_SRC_EXT ${_SRC} EXT)
if((${_SRC_EXT} MATCHES ".h") OR (${_SRC_EXT} MATCHES ".hpp"))
source_group("Header Files" FILES ${_SRC})
else()
source_group("Source Files" FILES ${SRC})
source_group("Source Files" FILES ${_SRC})
endif()
endforeach()
unset(_SRC)
unset(_SRC_EXT)
endmacro()
@@ -76,11 +145,6 @@ endmacro()
macro(SETUP_LIBDIRS)
# see "cmake --help-policy CMP0003"
if(COMMAND cmake_policy)
cmake_policy(SET CMP0003 NEW)
endif()
link_directories(${JPEG_LIBPATH} ${PNG_LIBPATH} ${ZLIB_LIBPATH} ${FREETYPE_LIBPATH})
if(WITH_PYTHON) # AND NOT WITH_PYTHON_MODULE # WIN32 needs
@@ -118,7 +182,7 @@ macro(SETUP_LIBDIRS)
link_directories(${SNDFILE_LIBPATH})
endif()
if(WITH_SAMPLERATE)
link_directories(${LIBSAMPLERATE_LIBPATH})
link_directories(${SAMPLERATE_LIBPATH})
endif()
if(WITH_FFTW3)
link_directories(${FFTW3_LIBPATH})
@@ -139,19 +203,29 @@ endmacro()
macro(setup_liblinks
target)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${PLATFORM_LINKFLAGS} ")
target_link_libraries(${target} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} ${JPEG_LIBRARIES} ${PNG_LIBRARIES} ${ZLIB_LIBRARIES} ${LLIBS})
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${PLATFORM_LINKFLAGS}")
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} ${PLATFORM_LINKFLAGS_DEBUG}")
target_link_libraries(${target}
${OPENGL_gl_LIBRARY}
${OPENGL_glu_LIBRARY}
${JPEG_LIBRARIES}
${PNG_LIBRARIES}
${ZLIB_LIBRARIES}
${PLATFORM_LINKLIBS})
# since we are using the local libs for python when compiling msvc projects, we need to add _d when compiling debug versions
if(WITH_PYTHON) # AND NOT WITH_PYTHON_MODULE # WIN32 needs
target_link_libraries(${target} ${PYTHON_LINKFLAGS})
if(WIN32 AND NOT UNIX)
target_link_libraries(${target} debug ${PYTHON_LIBRARY}_d)
target_link_libraries(${target} optimized ${PYTHON_LIBRARY})
file_list_suffix(PYTHON_LIBRARIES_DEBUG "${PYTHON_LIBRARIES}" "_d")
target_link_libraries_debug(${target} "${PYTHON_LIBRARIES_DEBUG}")
target_link_libraries_optimized(${target} "${PYTHON_LIBRARIES}")
unset(PYTHON_LIBRARIES_DEBUG)
else()
target_link_libraries(${target} ${PYTHON_LIBRARY})
target_link_libraries(${target} ${PYTHON_LIBRARIES})
endif()
endif()
@@ -159,14 +233,18 @@ macro(setup_liblinks
target_link_libraries(${target} ${GLEW_LIBRARY})
endif()
target_link_libraries(${target} ${OPENGL_glu_LIBRARY} ${JPEG_LIBRARIES} ${PNG_LIBRARIES} ${ZLIB_LIBRARIES})
target_link_libraries(${target} ${FREETYPE_LIBRARY})
target_link_libraries(${target}
${OPENGL_glu_LIBRARY}
${JPEG_LIBRARIES}
${PNG_LIBRARIES}
${ZLIB_LIBRARIES}
${FREETYPE_LIBRARY})
if(WITH_INTERNATIONAL)
target_link_libraries(${target} ${GETTEXT_LIB})
if(WIN32 AND NOT UNIX)
target_link_libraries(${target} ${ICONV_LIB})
target_link_libraries(${target} ${ICONV_LIBRARIES})
endif()
endif()
@@ -174,65 +252,76 @@ macro(setup_liblinks
target_link_libraries(${target} ${OPENAL_LIBRARY})
endif()
if(WITH_FFTW3)
target_link_libraries(${target} ${FFTW3_LIB})
target_link_libraries(${target} ${FFTW3_LIBRARIES})
endif()
if(WITH_JACK)
target_link_libraries(${target} ${JACK_LIB})
target_link_libraries(${target} ${JACK_LIBRARIES})
endif()
if(WITH_CODEC_SNDFILE)
target_link_libraries(${target} ${SNDFILE_LIB})
target_link_libraries(${target} ${SNDFILE_LIBRARIES})
endif()
if(WITH_SAMPLERATE)
target_link_libraries(${target} ${LIBSAMPLERATE_LIB})
target_link_libraries(${target} ${SAMPLERATE_LIBRARIES})
endif()
if(WITH_SDL)
target_link_libraries(${target} ${SDL_LIBRARY})
endif()
if(WITH_CODEC_QUICKTIME)
target_link_libraries(${target} ${QUICKTIME_LIB})
target_link_libraries(${target} ${QUICKTIME_LIBRARIES})
endif()
if(WITH_IMAGE_TIFF)
target_link_libraries(${target} ${TIFF_LIBRARY})
endif()
if(WITH_IMAGE_OPENEXR)
if(WIN32 AND NOT UNIX)
foreach(loop_var ${OPENEXR_LIB})
target_link_libraries(${target} debug ${loop_var}_d)
target_link_libraries(${target} optimized ${loop_var})
endforeach()
file_list_suffix(OPENEXR_LIBRARIES_DEBUG "${OPENEXR_LIBRARIES}" "_d")
target_link_libraries_debug(${target} "${OPENEXR_LIBRARIES_DEBUG}")
target_link_libraries_optimized(${target} "${OPENEXR_LIBRARIES}")
unset(OPENEXR_LIBRARIES_DEBUG)
else()
target_link_libraries(${target} ${OPENEXR_LIB})
target_link_libraries(${target} ${OPENEXR_LIBRARIES})
endif()
endif()
if(WITH_IMAGE_OPENJPEG AND UNIX AND NOT APPLE)
target_link_libraries(${target} ${OPENJPEG_LIB})
target_link_libraries(${target} ${OPENJPEG_LIBRARIES})
endif()
if(WITH_CODEC_FFMPEG)
target_link_libraries(${target} ${FFMPEG_LIB})
target_link_libraries(${target} ${FFMPEG_LIBRARIES})
endif()
if(WITH_OPENCOLLADA)
if(WIN32 AND NOT UNIX)
foreach(loop_var ${OPENCOLLADA_LIB})
target_link_libraries(${target} debug ${loop_var}_d)
target_link_libraries(${target} optimized ${loop_var})
endforeach()
target_link_libraries(${target} debug ${PCRE_LIB}_d)
target_link_libraries(${target} optimized ${PCRE_LIB})
file_list_suffix(OPENCOLLADA_LIBRARIES_DEBUG "${OPENCOLLADA_LIBRARIES}" "_d")
target_link_libraries_debug(${target} "${OPENCOLLADA_LIBRARIES_DEBUG}")
target_link_libraries_optimized(${target} "${OPENCOLLADA_LIBRARIES}")
unset(OPENCOLLADA_LIBRARIES_DEBUG)
file_list_suffix(PCRE_LIB_DEBUG "${PCRE_LIB}" "_d")
target_link_libraries_debug(${target} "${PCRE_LIB_DEBUG}")
target_link_libraries_optimized(${target} "${PCRE_LIB}")
unset(PCRE_LIB_DEBUG)
if(EXPAT_LIB)
target_link_libraries(${target} debug ${EXPAT_LIB}_d)
target_link_libraries(${target} optimized ${EXPAT_LIB})
file_list_suffix(EXPAT_LIB_DEBUG "${EXPAT_LIB}" "_d")
target_link_libraries_debug(${target} "${EXPAT_LIB_DEBUG}")
target_link_libraries_optimized(${target} "${EXPAT_LIB}")
unset(EXPAT_LIB_DEBUG)
endif()
else()
target_link_libraries(${target} ${OPENCOLLADA_LIB})
target_link_libraries(${target} ${PCRE_LIB})
target_link_libraries(${target} ${EXPAT_LIB})
target_link_libraries(${target}
${OPENCOLLADA_LIBRARIES}
${PCRE_LIB}
${EXPAT_LIB})
endif()
endif()
if(WITH_MEM_JEMALLOC)
target_link_libraries(${target} ${JEMALLOC_LIBRARY})
target_link_libraries(${target} ${JEMALLOC_LIBRARIES})
endif()
if(WITH_INPUT_NDOF)
target_link_libraries(${target} ${NDOF_LIBRARIES})
endif()
if(WIN32 AND NOT UNIX)
target_link_libraries(${target} ${PTHREADS_LIB})
target_link_libraries(${target} ${PTHREADS_LIBRARIES})
endif()
endmacro()
@@ -303,6 +392,7 @@ macro(remove_strict_flags)
remove_flag("-Wstrict-prototypes")
remove_flag("-Wunused-parameter")
remove_flag("-Wwrite-strings")
remove_flag("-Wundef")
remove_flag("-Wshadow")
remove_flag("-Werror=[^ ]+")
remove_flag("-Werror")
@@ -472,4 +562,13 @@ macro(blender_project_hack_post)
unset(_reset_standard_cflags_rel)
unset(_reset_standard_cxxflags_rel)
# ------------------------------------------------------------------
# workaround for omission in cmake 2.8.4's GNU.cmake, fixed in 2.8.5
if(CMAKE_COMPILER_IS_GNUCC)
if(NOT DARWIN)
set(CMAKE_INCLUDE_SYSTEM_FLAG_C "-isystem ")
endif()
endif()
endmacro()

View File

@@ -43,7 +43,7 @@ if(CMAKE_SYSTEM_NAME MATCHES "Linux")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "${PROJECT_DESCRIPTION}")
set(CPACK_PACKAGE_RELOCATABLE "false")
set(CPACK_RPM_PACKAGE_LICENSE "GPLv2")
set(CPACK_RPM_PACKAGE_GROUP "Amusements/Graphics")
set(CPACK_RPM_PACKAGE_GROUP "Amusements/Multimedia")
set(CPACK_RPM_USER_BINARY_SPECFILE "${CMAKE_SOURCE_DIR}/build_files/package_spec/rpm/blender.spec.in")
endif()
endif()
@@ -75,14 +75,14 @@ endmacro()
if(APPLE)
add_package_archive(
"blender-${BLENDER_VERSION}-r${BUILD_REV}-OSX-${CMAKE_OSX_ARCHITECTURES}"
"${PROJECT_NAME}-${BLENDER_VERSION}-r${BUILD_REV}-OSX-${CMAKE_OSX_ARCHITECTURES}"
"zip")
elseif(UNIX)
# platform name could be tweaked, to include glibc, and ensure processor is correct (i386 vs i686)
string(TOLOWER ${CMAKE_SYSTEM_NAME} PACKAGE_SYSTEM_NAME)
add_package_archive(
"blender-${BLENDER_VERSION}-r${BUILD_REV}-${PACKAGE_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR}"
"${PROJECT_NAME}-${BLENDER_VERSION}-r${BUILD_REV}-${PACKAGE_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR}"
"tar.bz2")
endif()

View File

@@ -9,6 +9,7 @@ Release: @CPACK_RPM_PACKAGE_RELEASE@%{?dist}
License: @CPACK_RPM_PACKAGE_LICENSE@
Group: @CPACK_RPM_PACKAGE_GROUP@
Vendor: @CPACK_RPM_PACKAGE_VENDOR@
Epoch: 1
%define _rpmdir @CPACK_RPM_DIRECTORY@
%define _rpmfilename @CPACK_RPM_FILE_NAME@

View File

@@ -76,11 +76,6 @@ BF_GETTEXT_INC = '${BF_GETTEXT}/include'
BF_GETTEXT_LIB = 'gettextpo intl'
BF_GETTEXT_LIBPATH = '${BF_GETTEXT}/lib'
WITH_BF_FTGL = 'false'
BF_FTGL = '#extern/bFTGL'
BF_FTGL_INC = '${BF_FTGL}/include'
BF_FTGL_LIB = 'extern_ftgl'
WITH_BF_GAMEENGINE='false'
WITH_BF_BULLET = 'true'

View File

@@ -14,21 +14,30 @@ USE_SDK=True
################### Cocoa & architecture settings ##################
#############################################################################
WITH_GHOST_COCOA=True
MACOSX_ARCHITECTURE = 'i386' # valid archs: ppc, i386, ppc64, x86_64
MACOSX_ARCHITECTURE = 'x86_64' # valid archs: ppc, i386, ppc64, x86_64
cmd = 'uname -p'
MAC_PROC=commands.getoutput(cmd)
cmd = 'uname -r'
cmd_res=commands.getoutput(cmd)
if cmd_res[0]=='7':
if cmd_res[:1]=='7':
MAC_CUR_VER='10.3'
elif cmd_res[0]=='8':
elif cmd_res[:1]=='8':
MAC_CUR_VER='10.4'
elif cmd_res[0]=='9':
elif cmd_res[:1]=='9':
MAC_CUR_VER='10.5'
elif cmd_res[0]=='10':
elif cmd_res[:2]=='10':
MAC_CUR_VER='10.6'
elif cmd_res[:2]=='11':
MAC_CUR_VER='10.7'
cmd = 'xcodebuild -version'
cmd_xcode=commands.getoutput(cmd)
XCODE_CUR_VER=cmd_xcode
cmd = 'xcodebuild -showsdks'
cmd_sdk=commands.getoutput(cmd)
MACOSX_SDK_CHECK=cmd_sdk
if MACOSX_ARCHITECTURE == 'x86_64' or MACOSX_ARCHITECTURE == 'ppc64':
USE_QTKIT=True # Carbon quicktime is not available for 64bit
@@ -37,8 +46,8 @@ if MACOSX_ARCHITECTURE == 'x86_64' or MACOSX_ARCHITECTURE == 'ppc64':
# Default target OSX settings per architecture
# Can be customized
if MACOSX_ARCHITECTURE == 'ppc':
# ppc release are now made for 10.4
if MACOSX_ARCHITECTURE == 'ppc' and MAC_CUR_VER == '10.4':
# all releases are now made for 10.5 !
# MAC_MIN_VERS = '10.3'
# MACOSX_SDK='/Developer/SDKs/MacOSX10.3.9.sdk'
# LCGDIR = '#../lib/darwin-6.1-powerpc'
@@ -50,7 +59,7 @@ if MACOSX_ARCHITECTURE == 'ppc':
LCGDIR = '#../lib/darwin-8.0.0-powerpc'
CC = 'gcc-4.0'
CXX = 'g++-4.0'
elif MACOSX_ARCHITECTURE == 'i386':
elif MACOSX_ARCHITECTURE == 'i386' and MAC_CUR_VER == '10.4':
MAC_MIN_VERS = '10.4'
MACOSX_DEPLOYMENT_TARGET = '10.4'
MACOSX_SDK='/Developer/SDKs/MacOSX10.4u.sdk'
@@ -58,12 +67,22 @@ elif MACOSX_ARCHITECTURE == 'i386':
CC = 'gcc-4.0'
CXX = 'g++-4.0'
else :
MAC_MIN_VERS = '10.5'
MACOSX_DEPLOYMENT_TARGET = '10.5'
MACOSX_SDK='/Developer/SDKs/MacOSX10.5.sdk'
LCGDIR = '#../lib/darwin-9.x.universal'
CC = 'gcc-4.2'
CXX = 'g++-4.2'
if 'Mac OS X 10.5' in MACOSX_SDK_CHECK:
# OSX 10.5/6 with Xcode 3.x
MAC_MIN_VERS = '10.5'
MACOSX_DEPLOYMENT_TARGET = '10.5'
MACOSX_SDK='/Developer/SDKs/MacOSX10.5.sdk'
LCGDIR = '#../lib/darwin-9.x.universal'
CC = 'gcc-4.2'
CXX = 'g++-4.2'
else:
# OSX 10.6/7 with Xcode 4.x
MAC_MIN_VERS = '10.6'
MACOSX_DEPLOYMENT_TARGET = '10.6'
MACOSX_SDK='/Developer/SDKs/MacOSX10.6.sdk'
LCGDIR = '#../lib/darwin-9.x.universal'
CC = 'gcc-4.2'
CXX = 'g++-4.2'
LIBDIR = '${LCGDIR}'
@@ -71,8 +90,8 @@ LIBDIR = '${LCGDIR}'
################### Dependency settings ##################
#############################################################################
#Defaults openMP to true if compiler (currently only gcc 4.2) handles it
if CC == 'gcc-4.2':
#Defaults openMP to true if compiler handles it
if CC == 'gcc-4.2' or CC == 'llvm-gcc-4.2':
WITH_BF_OPENMP = True # multithreading for fluids, cloth and smoke
else:
WITH_BF_OPENMP = False
@@ -85,14 +104,26 @@ BF_FFMPEG_LIBPATH='${BF_FFMPEG}/lib'
BF_FFMPEG_LIB = 'avcodec avdevice avformat avutil mp3lame swscale x264 xvidcore theora theoradec theoraenc vorbis vorbisenc vorbisfile ogg bz2'
#bz2 is a standard osx dynlib
# python 3.1 uses precompiled libraries in bf svn /lib by default
BF_PYTHON_VERSION = '3.2'
BF_PYTHON = LIBDIR + '/python'
BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}'
# BF_PYTHON_BINARY = '${BF_PYTHON}/bin/python${BF_PYTHON_VERSION}'
BF_PYTHON_LIB = 'python${BF_PYTHON_VERSION}'
BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib/python${BF_PYTHON_VERSION}'
# BF_PYTHON_LINKFLAGS = ['-u', '_PyMac_Error', '-framework', 'System']
WITH_OSX_STATICPYTHON = True
if WITH_OSX_STATICPYTHON:
# python 3.2 uses precompiled libraries in bf svn /lib by default
BF_PYTHON = LIBDIR + '/python'
BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}'
# BF_PYTHON_BINARY = '${BF_PYTHON}/bin/python${BF_PYTHON_VERSION}'
BF_PYTHON_LIB = 'python${BF_PYTHON_VERSION}'
BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib/python${BF_PYTHON_VERSION}'
# BF_PYTHON_LINKFLAGS = ['-u', '_PyMac_Error', '-framework', 'System']
else:
# python 3.2 uses Python-framework additionally installed in /Library/Frameworks
BF_PYTHON = '/Library/Frameworks/Python.framework/Versions/'
BF_PYTHON_INC = '${BF_PYTHON}${BF_PYTHON_VERSION}/include/python${BF_PYTHON_VERSION}m'
BF_PYTHON_BINARY = '${BF_PYTHON}${BF_PYTHON_VERSION}/bin/python${BF_PYTHON_VERSION}'
#BF_PYTHON_LIB = ''
BF_PYTHON_LIBPATH = '${BF_PYTHON}${BF_PYTHON_VERSION}/lib/python${BF_PYTHON_VERSION}/config-3.2m'
WITH_BF_OPENAL = True
#different lib must be used following version of gcc
@@ -188,8 +219,8 @@ BF_GETTEXT_INC = '${BF_GETTEXT}/include'
BF_GETTEXT_LIB = 'intl'
BF_GETTEXT_LIBPATH = '${BF_GETTEXT}/lib'
WITH_BF_GAMEENGINE=True
WITH_BF_PLAYER = False
WITH_BF_GAMEENGINE = True
WITH_BF_PLAYER = True
WITH_BF_BULLET = True
BF_BULLET = '#extern/bullet2/src'
@@ -240,7 +271,7 @@ BF_OPENGL_LIBPATH = '/System/Library/Frameworks/OpenGL.framework/Libraries'
BF_OPENGL_LINKFLAGS = ['-framework', 'OpenGL']
#OpenCollada flags
WITH_BF_COLLADA = False
WITH_BF_COLLADA = True
BF_COLLADA = '#source/blender/collada'
BF_COLLADA_INC = '${BF_COLLADA}'
BF_COLLADA_LIB = 'bf_collada'
@@ -264,7 +295,9 @@ if MACOSX_ARCHITECTURE == 'i386':
BF_RAYOPTIMIZATION_SSE_FLAGS = ['-msse']
elif MACOSX_ARCHITECTURE == 'x86_64':
BF_RAYOPTIMIZATION_SSE_FLAGS = ['-msse','-msse2']
# SpaceNavigator and related 3D mice, driver must be 3DxWare 10 Beta 4 (Mac OS X) or later !
WITH_BF_3DMOUSE = True
#############################################################################
################### various compile settings and flags ##################
@@ -283,28 +316,36 @@ CPPFLAGS = []+ARCH_FLAGS
CCFLAGS = ['-pipe','-funsigned-char']+ARCH_FLAGS
CXXFLAGS = ['-pipe','-funsigned-char']+ARCH_FLAGS
if WITH_GHOST_COCOA==True:
if WITH_GHOST_COCOA:
PLATFORM_LINKFLAGS = ['-fexceptions','-framework','CoreServices','-framework','Foundation','-framework','IOKit','-framework','AppKit','-framework','Cocoa','-framework','Carbon','-framework','AudioUnit','-framework','AudioToolbox','-framework','CoreAudio','-framework','OpenAL']+ARCH_FLAGS
else:
PLATFORM_LINKFLAGS = ['-fexceptions','-framework','CoreServices','-framework','Foundation','-framework','IOKit','-framework','AppKit','-framework','Carbon','-framework','AGL','-framework','AudioUnit','-framework','AudioToolbox','-framework','CoreAudio','-framework','OpenAL']+ARCH_FLAGS
if WITH_BF_QUICKTIME == True:
if USE_QTKIT == True:
if WITH_BF_QUICKTIME:
if USE_QTKIT:
PLATFORM_LINKFLAGS = PLATFORM_LINKFLAGS+['-framework','QTKit']
else:
PLATFORM_LINKFLAGS = PLATFORM_LINKFLAGS+['-framework','QuickTime']
#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']
if not WITH_OSX_STATICPYTHON:
PLATFORM_LINKFLAGS = PLATFORM_LINKFLAGS+['-framework','Python']
# some flags shuffling for different Os versions
#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
#for 10.7.sdk, SystemStubs needs to be excluded (lib doesn't exist anymore)
if MACOSX_DEPLOYMENT_TARGET == '10.7':
LLIBS = ['stdc++']
else:
LLIBS = ['stdc++', 'SystemStubs']
# some flags shuffling for different OS versions
if MAC_MIN_VERS == '10.3':
CFLAGS = ['-fuse-cxa-atexit']+CFLAGS
CXXFLAGS = ['-fuse-cxa-atexit']+CXXFLAGS
PLATFORM_LINKFLAGS = ['-fuse-cxa-atexit']+PLATFORM_LINKFLAGS
LLIBS.append('crt3.o')
if USE_SDK==True:
if USE_SDK:
SDK_FLAGS=['-isysroot', MACOSX_SDK,'-mmacosx-version-min='+MAC_MIN_VERS,'-arch',MACOSX_ARCHITECTURE]
PLATFORM_LINKFLAGS = ['-mmacosx-version-min='+MAC_MIN_VERS,'-Wl','-isysroot',MACOSX_SDK,'-arch',MACOSX_ARCHITECTURE]+PLATFORM_LINKFLAGS
CCFLAGS=SDK_FLAGS+CCFLAGS

View File

@@ -1,4 +1,4 @@
LCGDIR = '../lib/linux2'
LCGDIR = '../lib/linux'
LIBDIR = "${LCGDIR}"
BF_PYTHON_ABI_FLAGS = 'm' # Most common for linux distros
@@ -93,7 +93,7 @@ BF_GETTEXT_LIBPATH = '${BF_GETTEXT}/lib'
#BF_GETTEXT_LIB_STATIC = '${BF_GETTEXT}/lib/libgettextlib.a'
WITH_BF_GAMEENGINE = True
WITH_BF_PLAYER = False
WITH_BF_PLAYER = True
WITH_BF_BULLET = True
BF_BULLET = '#extern/bullet2/src'
@@ -192,6 +192,14 @@ WITH_BF_OPENMP = True
WITH_BF_RAYOPTIMIZATION = True
BF_RAYOPTIMIZATION_SSE_FLAGS = ['-msse','-pthread']
#SpaceNavigator and friends
WITH_BF_3DMOUSE = True
BF_3DMOUSE = '/usr'
BF_3DMOUSE_INC = '${BF_3DMOUSE}/include'
BF_3DMOUSE_LIBPATH = '${BF_3DMOUSE}/lib'
BF_3DMOUSE_LIB = 'spnav'
BF_3DMOUSE_LIB_STATIC = '${BF_3DMOUSE_LIBPATH}/libspnav.a'
##
CC = 'gcc'
CXX = 'g++'
@@ -233,8 +241,8 @@ BF_PROFILE_LINKFLAGS = ['-pg']
BF_DEBUG = False
BF_DEBUG_CCFLAGS = ['-g', '-D_DEBUG']
BF_BUILDDIR = '../build/linux2'
BF_INSTALLDIR='../install/linux2'
BF_BUILDDIR = '../build/linux'
BF_INSTALLDIR='../install/linux'
#Link against pthread
PLATFORM_LINKFLAGS = ['-pthread']

View File

@@ -126,9 +126,10 @@ WITH_BF_BINRELOC = False
# enable ffmpeg support
WITH_BF_FFMPEG = True # -DWITH_FFMPEG
BF_FFMPEG = LIBDIR + '/ffmpeg'
BF_FFMPEG_LIB = 'avformat-52 avcodec-52 avdevice-52 avutil-50 swscale-0'
BF_FFMPEG_LIB = 'avformat-53 avcodec-53 avdevice-53 avutil-51 swscale-2'
BF_FFMPEG_INC = '${BF_FFMPEG}/include'
BF_FFMPEG_LIBPATH = '${BF_FFMPEG}/lib'
BF_FFMPEG_DLL = '${BF_FFMPEG_LIBPATH}/avformat-53.dll ${BF_FFMPEG_LIBPATH}/avcodec-53.dll ${BF_FFMPEG_LIBPATH}/avdevice-53.dll ${BF_FFMPEG_LIBPATH}/avutil-51.dll ${BF_FFMPEG_LIBPATH}/swscale-2.dll'
WITH_BF_OPENJPEG = True
BF_OPENJPEG = '#extern/libopenjpeg'

View File

@@ -18,9 +18,10 @@ BF_OPENAL_LIB = 'wrap_oal'
BF_OPENAL_LIBPATH = '${BF_OPENAL}/lib'
WITH_BF_FFMPEG = False
BF_FFMPEG_LIB = 'avformat-52 avcodec-52 avdevice-52 avutil-50 swscale-0'
BF_FFMPEG_LIB = 'avformat-53 avcodec-53 avdevice-53 avutil-51 swscale-2'
BF_FFMPEG_LIBPATH = LIBDIR + '/ffmpeg/lib'
BF_FFMPEG_INC = LIBDIR + '/ffmpeg/include'
BF_FFMPEG_DLL = '${BF_FFMPEG_LIBPATH}/avformat-53.dll ${BF_FFMPEG_LIBPATH}/avcodec-53.dll ${BF_FFMPEG_LIBPATH}/avdevice-53.dll ${BF_FFMPEG_LIBPATH}/avutil-51.dll ${BF_FFMPEG_LIBPATH}/swscale-2.dll'
BF_LIBSAMPLERATE = LIBDIR + '/samplerate'
BF_LIBSAMPLERATE_INC = '${BF_LIBSAMPLERATE}/include'
@@ -173,7 +174,7 @@ C_WARN = ['-Wno-char-subscripts', '-Wdeclaration-after-statement', '-Wstrict-pro
CC_WARN = [ '-Wall' ]
LLIBS = ['-lshell32', '-lshfolder', '-lgdi32', '-lmsvcrt', '-lwinmm', '-lmingw32', '-lm', '-lws2_32', '-lz', '-lstdc++','-lole32','-luuid']
LLIBS = ['-lshell32', '-lshfolder', '-lgdi32', '-lmsvcrt', '-lwinmm', '-lmingw32', '-lm', '-lws2_32', '-lz', '-lstdc++','-lole32','-luuid', '-lwsock32']
PLATFORM_LINKFLAGS = ['--stack,2097152']

View File

@@ -6,7 +6,8 @@ WITH_BF_FFMPEG = True # -DWITH_FFMPEG
BF_FFMPEG = LIBDIR +'/ffmpeg'
BF_FFMPEG_INC = '${BF_FFMPEG}/include ${BF_FFMPEG}/include/msvc'
BF_FFMPEG_LIBPATH='${BF_FFMPEG}/lib'
BF_FFMPEG_LIB = 'avformat-52.lib avcodec-52.lib avdevice-52.lib avutil-50.lib swscale-0.lib'
BF_FFMPEG_LIB = 'avformat-53.lib avcodec-53.lib avdevice-53.lib avutil-51.lib swscale-2.lib'
BF_FFMPEG_DLL = '${BF_FFMPEG_LIBPATH}/avformat-53.dll ${BF_FFMPEG_LIBPATH}/avcodec-53.dll ${BF_FFMPEG_LIBPATH}/avdevice-53.dll ${BF_FFMPEG_LIBPATH}/avutil-51.dll ${BF_FFMPEG_LIBPATH}/swscale-2.dll'
BF_PYTHON = LIBDIR + '/python'
BF_PYTHON_VERSION = '3.2'
@@ -39,7 +40,7 @@ BF_JACK_INC = '${BF_JACK}/include ${BF_FFMPEG}/include/msvc'
BF_JACK_LIB = 'libjack'
BF_JACK_LIBPATH = '${BF_JACK}/lib'
WITH_BF_SNDFILE = False
WITH_BF_SNDFILE = True
BF_SNDFILE = LIBDIR + '/sndfile'
BF_SNDFILE_INC = '${BF_SNDFILE}/include'
BF_SNDFILE_LIB = 'libsndfile-1'
@@ -99,7 +100,7 @@ BF_GETTEXT_LIB = 'gnu_gettext'
BF_GETTEXT_LIBPATH = '${BF_GETTEXT}/lib'
WITH_BF_GAMEENGINE = True
WITH_BF_PLAYER = False
WITH_BF_PLAYER = True
WITH_BF_BULLET = True
BF_BULLET = '#extern/bullet2/src'
@@ -118,7 +119,7 @@ BF_FREETYPE_INC = '${BF_FREETYPE}/include ${BF_FREETYPE}/include/freetype2'
BF_FREETYPE_LIB = 'freetype2ST'
BF_FREETYPE_LIBPATH = '${BF_FREETYPE}/lib'
WITH_BF_QUICKTIME = True # -DWITH_QUICKTIME
WITH_BF_QUICKTIME = False # -DWITH_QUICKTIME
BF_QUICKTIME = LIBDIR + '/QTDevWin'
BF_QUICKTIME_INC = '${BF_QUICKTIME}/CIncludes'
BF_QUICKTIME_LIB = 'qtmlClient'
@@ -149,6 +150,8 @@ BF_OPENCOLLADA_INC = '${BF_OPENCOLLADA}/include'
BF_OPENCOLLADA_LIB = 'OpenCOLLADAStreamWriter OpenCOLLADASaxFrameworkLoader OpenCOLLADAFramework OpenCOLLADABaseUtils GeneratedSaxParser MathMLSolver xml2 pcre buffer ftoa UTF'
BF_OPENCOLLADA_LIBPATH = '${BF_OPENCOLLADA}/lib'
WITH_BF_3DMOUSE = True
#Ray trace optimization
WITH_BF_RAYOPTIMIZATION = True
BF_RAYOPTIMIZATION_SSE_FLAGS = ['/arch:SSE']
@@ -170,7 +173,7 @@ BGE_CXXFLAGS = ['/O2', '/EHsc', '/GR', '/fp:fast', '/arch:SSE']
BF_DEBUG_CCFLAGS = ['/Zi', '/FR${TARGET}.sbr']
CPPFLAGS = ['-DWIN32','-D_CONSOLE', '-D_LIB', '-DFTGL_LIBRARY_STATIC', '-D_CRT_SECURE_NO_DEPRECATE']
CPPFLAGS = ['-DWIN32','-D_CONSOLE', '-D_LIB', '-D_CRT_SECURE_NO_DEPRECATE']
REL_CFLAGS = ['-O2', '-DNDEBUG']
REL_CCFLAGS = ['-O2', '-DNDEBUG']
REL_CXXFLAGS = ['-O2', '-DNDEBUG']
@@ -181,7 +184,7 @@ CXX_WARN = []
LLIBS = ['ws2_32', 'vfw32', 'winmm', 'kernel32', 'user32', 'gdi32', 'comdlg32', 'advapi32', 'shfolder', 'shell32', 'ole32', 'oleaut32', 'uuid']
PLATFORM_LINKFLAGS = ['/SUBSYSTEM:CONSOLE','/MACHINE:IX86','/STACK:2097152','/INCREMENTAL:NO', '/LARGEADDRESSAWARE']
PLATFORM_LINKFLAGS = ['/SUBSYSTEM:CONSOLE','/MACHINE:IX86','/STACK:2097152','/INCREMENTAL:NO', '/LARGEADDRESSAWARE', '/NODEFAULTLIB:msvcrt.lib', '/NODEFAULTLIB:msvcmrt.lib', '/NODEFAULTLIB:msvcurt.lib', '/NODEFAULTLIB:msvcrtd.lib']
# # Todo
# BF_PROFILE_CCFLAGS = ['-pg', '-g ']

View File

@@ -6,7 +6,8 @@ WITH_BF_FFMPEG = True # -DWITH_FFMPEG
BF_FFMPEG = LIBDIR +'/ffmpeg'
BF_FFMPEG_INC = '${BF_FFMPEG}/include ${BF_FFMPEG}/include/msvc '
BF_FFMPEG_LIBPATH='${BF_FFMPEG}/lib'
BF_FFMPEG_LIB = 'avformat-52.lib avcodec-52.lib avdevice-52.lib avutil-50.lib swscale-0.lib'
BF_FFMPEG_LIB = 'avformat-53.lib avcodec-53.lib avdevice-53.lib avutil-51.lib swscale-2.lib'
BF_FFMPEG_DLL = '${BF_FFMPEG_LIBPATH}/avformat-53.dll ${BF_FFMPEG_LIBPATH}/avcodec-53.dll ${BF_FFMPEG_LIBPATH}/avdevice-53.dll ${BF_FFMPEG_LIBPATH}/avutil-51.dll ${BF_FFMPEG_LIBPATH}/swscale-2.dll'
BF_PYTHON = LIBDIR + '/python'
BF_PYTHON_VERSION = '3.2'
@@ -50,6 +51,8 @@ BF_SDL_INC = '${BF_SDL}/include'
BF_SDL_LIB = 'SDL.lib'
BF_SDL_LIBPATH = '${BF_SDL}/lib'
WITH_BF_JACK = False
BF_PTHREADS = LIBDIR + '/pthreads'
BF_PTHREADS_INC = '${BF_PTHREADS}/include'
BF_PTHREADS_LIB = 'pthreadVC2'
@@ -101,7 +104,7 @@ BF_GETTEXT_LIB = 'gettext'
BF_GETTEXT_LIBPATH = '${BF_GETTEXT}/lib'
WITH_BF_GAMEENGINE = True
WITH_BF_PLAYER = False
WITH_BF_PLAYER = True
WITH_BF_BULLET = True
BF_BULLET = '#extern/bullet2/src'
@@ -151,6 +154,8 @@ BF_OPENCOLLADA_INC = '${BF_OPENCOLLADA}/include'
BF_OPENCOLLADA_LIB = 'OpenCOLLADAStreamWriter OpenCOLLADASaxFrameworkLoader OpenCOLLADAFramework OpenCOLLADABaseUtils GeneratedSaxParser MathMLSolver xml2 pcre buffer ftoa UTF'
BF_OPENCOLLADA_LIBPATH = '${BF_OPENCOLLADA}/lib'
WITH_BF_3DMOUSE = True
#Ray trace optimization
WITH_BF_RAYOPTIMIZATION = True
BF_RAYOPTIMIZATION_SSE_FLAGS = ['/arch:SSE','/arch:SSE2']
@@ -170,9 +175,9 @@ CCFLAGS = ['/nologo', '/Ob1', '/J', '/W0', '/Gd', '/we4013', '/wd4018', '/wd4244
CXXFLAGS = ['/EHsc']
BGE_CXXFLAGS = ['/O2', '/EHsc', '/GR', '/fp:fast']
BF_DEBUG_CCFLAGS = ['/Zi', '/FR${TARGET}.sbr']
BF_DEBUG_CCFLAGS = ['/Zi', '/FR${TARGET}.sbr', '/Od']
CPPFLAGS = ['-DWIN32', '-D_CONSOLE', '-D_LIB', '-DFTGL_LIBRARY_STATIC', '-D_CRT_SECURE_NO_DEPRECATE']
CPPFLAGS = ['-DWIN32', '-D_CONSOLE', '-D_LIB', '-D_CRT_SECURE_NO_DEPRECATE']
REL_CFLAGS = ['-O2', '-DNDEBUG']
REL_CCFLAGS = ['-O2', '-DNDEBUG']
REL_CXXFLAGS = ['-O2', '-DNDEBUG']
@@ -188,7 +193,7 @@ if BF_DEBUG:
else:
BF_NUMJOBS=6
PLATFORM_LINKFLAGS = ['/SUBSYSTEM:CONSOLE','/MACHINE:X64','/STACK:2097152','/OPT:NOREF','/INCREMENTAL:NO']
PLATFORM_LINKFLAGS = ['/SUBSYSTEM:CONSOLE','/MACHINE:X64','/STACK:2097152','/OPT:NOREF','/INCREMENTAL:NO', '/NODEFAULTLIB:msvcrt.lib', '/NODEFAULTLIB:msvcmrt.lib', '/NODEFAULTLIB:msvcurt.lib', '/NODEFAULTLIB:msvcrtd.lib']
BF_BUILDDIR = '..\\build\\blender25-win64-vc'
BF_INSTALLDIR='..\\install\\blender25-win64-vc'

View File

@@ -206,6 +206,12 @@ def setup_staticlibs(lenv):
if lenv['WITH_BF_STATICJEMALLOC']:
statlibs += Split(lenv['BF_JEMALLOC_LIB_STATIC'])
if lenv['OURPLATFORM']=='linux':
if lenv['WITH_BF_3DMOUSE']:
libincs += Split(lenv['BF_3DMOUSE_LIBPATH'])
if lenv['WITH_BF_STATIC3DMOUSE']:
statlibs += Split(lenv['BF_3DMOUSE_LIB_STATIC'])
return statlibs, libincs
def setup_syslibs(lenv):
@@ -258,7 +264,10 @@ def setup_syslibs(lenv):
syslibs += Split(lenv['BF_PTHREADS_LIB'])
if lenv['WITH_BF_COLLADA']:
syslibs.append(lenv['BF_PCRE_LIB'])
syslibs += Split(lenv['BF_OPENCOLLADA_LIB'])
if lenv['BF_DEBUG']:
syslibs += [colladalib+'_d' for colladalib in Split(lenv['BF_OPENCOLLADA_LIB'])]
else:
syslibs += Split(lenv['BF_OPENCOLLADA_LIB'])
syslibs.append(lenv['BF_EXPAT_LIB'])
if not lenv['WITH_BF_STATICLIBSAMPLERATE']:
@@ -268,6 +277,11 @@ def setup_syslibs(lenv):
if not lenv['WITH_BF_STATICJEMALLOC']:
syslibs += Split(lenv['BF_JEMALLOC_LIB'])
if lenv['OURPLATFORM']=='linux':
if lenv['WITH_BF_3DMOUSE']:
if not lenv['WITH_BF_STATIC3DMOUSE']:
syslibs += Split(lenv['BF_3DMOUSE_LIB'])
syslibs += lenv['LLIBS']
return syslibs
@@ -287,6 +301,46 @@ def propose_priorities():
print "\t\t",new_priority, v
new_priority += 5
# emits the necessary file objects for creator.c, to be used in creating
# the final blender executable
def creator(env):
sources = ['creator.c']# + Blender.buildinfo(env, "dynamic") + Blender.resources
incs = ['#/intern/guardedalloc', '#/source/blender/blenlib', '#/source/blender/blenkernel', '#/source/blender/editors/include', '#/source/blender/blenloader', '#/source/blender/imbuf', '#/source/blender/renderconverter', '#/source/blender/render/extern/include', '#/source/blender/windowmanager', '#/source/blender/makesdna', '#/source/blender/makesrna', '#/source/gameengine/BlenderRoutines', '#/extern/glew/include', '#/source/blender/gpu', env['BF_OPENGL_INC']]
defs = []
if env['WITH_BF_QUICKTIME']:
incs.append(env['BF_QUICKTIME_INC'])
defs.append('WITH_QUICKTIME')
if env['WITH_BF_BINRELOC']:
incs.append('#/extern/binreloc/include')
defs.append('WITH_BINRELOC')
if env['WITH_BF_OPENEXR']:
defs.append('WITH_OPENEXR')
if env['WITH_BF_TIFF']:
defs.append('WITH_TIFF')
if not env['WITH_BF_SDL']:
defs.append('DISABLE_SDL')
if env['WITH_BF_PYTHON']:
incs.append('#/source/blender/python')
defs.append('WITH_PYTHON')
if env['BF_DEBUG']:
defs.append('_DEBUG')
if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'):
incs.append(env['BF_PTHREADS_INC'])
env.Append(CPPDEFINES=defs)
env.Append(CPPPATH=incs)
obj = [env.Object(root_build_dir+'source/creator/creator/creator', ['#source/creator/creator.c'])]
return obj
## TODO: see if this can be made in an emitter
def buildinfo(lenv, build_type):
"""
@@ -310,21 +364,21 @@ def buildinfo(lenv, build_type):
obj = []
if lenv['BF_BUILDINFO']:
lenv.Append (CPPDEFINES = ['BUILD_TIME="%s"'%(build_time),
'BUILD_DATE="%s"'%(build_date),
'BUILD_TYPE="%s"'%(build_type),
'BUILD_REV="%s"'%(build_rev),
'NAN_BUILDINFO',
'BUILD_PLATFORM="%s:%s"'%(platform.system(), platform.architecture()[0]),
lenv.Append (CPPDEFINES = ['BUILD_TIME=\\"%s\\"'%(build_time),
'BUILD_DATE=\\"%s\\"'%(build_date),
'BUILD_TYPE=\\"%s\\"'%(build_type),
'BUILD_REV=\\"%s\\"'%(build_rev),
'WITH_BUILDINFO',
'BUILD_PLATFORM=\\"%s:%s\\"'%(platform.system(), platform.architecture()[0]),
'BUILD_CFLAGS=\\"%s\\"'%(build_cflags),
'BUILD_CXXFLAGS=\\"%s\\"'%(build_cxxflags),
'BUILD_LINKFLAGS=\\"%s\\"'%(build_linkflags),
'BUILD_SYSTEM="SCons"'
'BUILD_SYSTEM=\\"SCons\\"'
])
lenv.Append (CPPPATH = [root_build_dir+'source/blender/blenkernel'])
obj = [lenv.Object (root_build_dir+'source/creator/%s_buildinfo'%build_type, [root_build_dir+'source/creator/buildinfo.c'])]
obj = [lenv.Object (root_build_dir+'source/creator/%s_buildinfo'%build_type, ['#source/creator/buildinfo.c'])]
return obj
@@ -482,7 +536,10 @@ def AppIt(target=None, source=None, env=None):
print("Installing to %s"%(installdir))
# TODO, use tar.
python_zip = 'python_' + osxarch + '.zip' # set specific python_arch.zip
print("unzipping to app-bundle: %s"%(python_zip))
if env['WITH_OSX_STATICPYTHON']:
print("unzipping to app-bundle: %s"%(python_zip))
else:
print("dynamic build - make sure to have python3.x-framework installed")
bldroot = env.Dir('.').abspath
binary = env['BINARYKIND']
@@ -515,16 +572,20 @@ def AppIt(target=None, source=None, env=None):
commands.getoutput(cmd)
cmd = 'cp %s/release/bin/%s/.Blanguages %s/%s.app/Contents/Resources/'%(bldroot,VERSION,installdir,binary)
commands.getoutput(cmd)
cmd = 'mkdir %s/%s.app/Contents/MacOS/%s/python/'%(installdir,binary, VERSION)
commands.getoutput(cmd)
cmd = 'unzip -q %s/release/%s -d %s/%s.app/Contents/MacOS/%s/python/'%(libdir,python_zip,installdir,binary,VERSION)
commands.getoutput(cmd)
cmd = 'cp -R %s/release/scripts %s/%s.app/Contents/MacOS/%s/'%(bldroot,installdir,binary,VERSION)
commands.getoutput(cmd)
cmd = 'cp -R %s/release/ui %s/%s.app/Contents/MacOS/%s/'%(bldroot,installdir,binary,VERSION)
commands.getoutput(cmd)
cmd = 'cp -R %s/release/io %s/%s.app/Contents/MacOS/%s/'%(bldroot,installdir,binary,VERSION)
commands.getoutput(cmd)
if env['WITH_OSX_STATICPYTHON']:
cmd = 'mkdir %s/%s.app/Contents/MacOS/%s/python/'%(installdir,binary, VERSION)
commands.getoutput(cmd)
cmd = 'unzip -q %s/release/%s -d %s/%s.app/Contents/MacOS/%s/python/'%(libdir,python_zip,installdir,binary,VERSION)
commands.getoutput(cmd)
if binary == 'blender':#not copy everything for blenderplayer
cmd = 'cp -R %s/release/scripts %s/%s.app/Contents/MacOS/%s/'%(bldroot,installdir,binary,VERSION)
commands.getoutput(cmd)
cmd = 'cp -R %s/release/ui %s/%s.app/Contents/MacOS/%s/'%(bldroot,installdir,binary,VERSION)
commands.getoutput(cmd)
cmd = 'cp -R %s/release/io %s/%s.app/Contents/MacOS/%s/'%(bldroot,installdir,binary,VERSION)
commands.getoutput(cmd)
cmd = 'chmod +x %s/%s.app/Contents/MacOS/%s'%(installdir,binary, binary)
commands.getoutput(cmd)
cmd = 'find %s/%s.app -name .svn -prune -exec rm -rf {} \;'%(installdir, binary)
@@ -714,23 +775,19 @@ class BlenderEnvironment(SConsEnvironment):
global vcp
print bc.HEADER+'Configuring program '+bc.ENDC+bc.OKGREEN+progname+bc.ENDC
lenv = self.Clone()
lenv.Append(LINKFLAGS = lenv['PLATFORM_LINKFLAGS'])
if lenv['OURPLATFORM'] in ('win32-vc', 'cygwin', 'win64-vc'):
lenv.Append(LINKFLAGS = lenv['PLATFORM_LINKFLAGS'])
lenv.Append(LINKFLAGS = ['/FORCE:MULTIPLE'])
if lenv['BF_DEBUG']:
lenv.Prepend(LINKFLAGS = ['/DEBUG','/PDB:'+progname+'.pdb'])
if lenv['OURPLATFORM']=='linux2':
lenv.Append(LINKFLAGS = lenv['PLATFORM_LINKFLAGS'])
lenv.Prepend(LINKFLAGS = ['/DEBUG','/PDB:'+progname+'.pdb','/NODEFAULTLIB:libcmt'])
if lenv['OURPLATFORM']=='linux':
if lenv['WITH_BF_PYTHON']:
lenv.Append(LINKFLAGS = lenv['BF_PYTHON_LINKFLAGS'])
if lenv['OURPLATFORM']=='sunos5':
lenv.Append(LINKFLAGS = lenv['PLATFORM_LINKFLAGS'])
if lenv['WITH_BF_PYTHON']:
lenv.Append(LINKFLAGS = lenv['BF_PYTHON_LINKFLAGS'])
if lenv['CXX'].endswith('CC'):
lenv.Replace(LINK = '$CXX')
if lenv['OURPLATFORM']=='darwin':
lenv.Append(LINKFLAGS = lenv['PLATFORM_LINKFLAGS'])
if lenv['WITH_BF_PYTHON']:
lenv.Append(LINKFLAGS = lenv['BF_PYTHON_LINKFLAGS'])
lenv.Append(LINKFLAGS = lenv['BF_OPENGL_LINKFLAGS'])

View File

@@ -78,7 +78,7 @@ def print_arguments(args, bc):
def validate_arguments(args, bc):
opts_list = [
'WITH_BF_PYTHON', 'WITH_BF_PYTHON_SAFETY', 'BF_PYTHON', 'BF_PYTHON_VERSION', 'BF_PYTHON_INC', 'BF_PYTHON_BINARY', 'BF_PYTHON_LIB', 'BF_PYTHON_LIBPATH', 'WITH_BF_STATICPYTHON', 'BF_PYTHON_LIB_STATIC', 'BF_PYTHON_DLL', 'BF_PYTHON_ABI_FLAGS',
'WITH_BF_PYTHON', 'WITH_BF_PYTHON_SAFETY', 'BF_PYTHON', 'BF_PYTHON_VERSION', 'BF_PYTHON_INC', 'BF_PYTHON_BINARY', 'BF_PYTHON_LIB', 'BF_PYTHON_LIBPATH', 'WITH_BF_STATICPYTHON', 'WITH_OSX_STATICPYTHON', 'BF_PYTHON_LIB_STATIC', 'BF_PYTHON_DLL', 'BF_PYTHON_ABI_FLAGS',
'WITH_BF_OPENAL', 'BF_OPENAL', 'BF_OPENAL_INC', 'BF_OPENAL_LIB', 'BF_OPENAL_LIBPATH', 'WITH_BF_STATICOPENAL', 'BF_OPENAL_LIB_STATIC',
'WITH_BF_SDL', 'BF_SDL', 'BF_SDL_INC', 'BF_SDL_LIB', 'BF_SDL_LIBPATH',
'BF_LIBSAMPLERATE', 'BF_LIBSAMPLERATE_INC', 'BF_LIBSAMPLERATE_LIB', 'BF_LIBSAMPLERATE_LIBPATH', 'WITH_BF_STATICLIBSAMPLERATE', 'BF_LIBSAMPLERATE_LIB_STATIC',
@@ -87,7 +87,7 @@ def validate_arguments(args, bc):
'BF_PTHREADS', 'BF_PTHREADS_INC', 'BF_PTHREADS_LIB', 'BF_PTHREADS_LIBPATH',
'WITH_BF_OPENEXR', 'BF_OPENEXR', 'BF_OPENEXR_INC', 'BF_OPENEXR_LIB', 'BF_OPENEXR_LIBPATH', 'WITH_BF_STATICOPENEXR', 'BF_OPENEXR_LIB_STATIC',
'WITH_BF_DDS', 'WITH_BF_CINEON', 'WITH_BF_HDR',
'WITH_BF_FFMPEG', 'BF_FFMPEG_LIB','BF_FFMPEG_EXTRA', 'BF_FFMPEG', 'BF_FFMPEG_INC',
'WITH_BF_FFMPEG', 'BF_FFMPEG_LIB','BF_FFMPEG_EXTRA', 'BF_FFMPEG', 'BF_FFMPEG_INC', 'BF_FFMPEG_DLL',
'WITH_BF_STATICFFMPEG', 'BF_FFMPEG_LIB_STATIC',
'WITH_BF_OGG', 'BF_OGG', 'BF_OGG_LIB',
'WITH_BF_JPEG', 'BF_JPEG', 'BF_JPEG_INC', 'BF_JPEG_LIB', 'BF_JPEG_LIBPATH',
@@ -121,6 +121,7 @@ def validate_arguments(args, bc):
'BF_OPENMP_INC',
'BF_OPENMP_LIBPATH',
'WITH_GHOST_COCOA',
'WITH_GHOST_SDL',
'USE_QTKIT',
'BF_FANCY', 'BF_QUIET', 'BF_LINE_OVERWRITE',
'BF_X264_CONFIG',
@@ -135,7 +136,7 @@ def validate_arguments(args, bc):
'BF_NO_ELBEEM',
'WITH_BF_CXX_GUARDEDALLOC',
'WITH_BF_JEMALLOC', 'WITH_BF_STATICJEMALLOC', 'BF_JEMALLOC', 'BF_JEMALLOC_INC', 'BF_JEMALLOC_LIBPATH', 'BF_JEMALLOC_LIB', 'BF_JEMALLOC_LIB_STATIC',
'BUILDBOT_BRANCH'
'BUILDBOT_BRANCH', 'WITH_BF_3DMOUSE', 'WITH_BF_STATIC3DMOUSE', 'BF_3DMOUSE', 'BF_3DMOUSE_INC', 'BF_3DMOUSE_LIB', 'BF_3DMOUSE_LIBPATH', 'BF_3DMOUSE_LIB_STATIC'
]
# Have options here that scons expects to be lists
@@ -148,7 +149,7 @@ def validate_arguments(args, bc):
'BF_PROFILE_CFLAGS', 'BF_PROFILE_CCFLAGS', 'BF_PROFILE_CXXFLAGS', 'BF_PROFILE_LINKFLAGS',
'BF_DEBUG_CFLAGS', 'BF_DEBUG_CCFLAGS', 'BF_DEBUG_CXXFLAGS',
'C_WARN', 'CC_WARN', 'CXX_WARN',
'LLIBS', 'PLATFORM_LINKFLAGS','MACOSX_ARCHITECTURE',
'LLIBS', 'PLATFORM_LINKFLAGS','MACOSX_ARCHITECTURE', 'MACOSX_SDK_CHECK', 'XCODE_CUR_VER',
]
@@ -158,7 +159,7 @@ def validate_arguments(args, bc):
'BF_BSC', 'BF_CONFIG',
'BF_PRIORITYLIST', 'BF_BUILDINFO','CC', 'CXX', 'BF_QUICKDEBUG',
'BF_LISTDEBUG', 'LCGDIR', 'BF_X264_CONFIG', 'BF_XVIDCORE_CONFIG',
'BF_UNIT_TEST']
'BF_UNIT_TEST', 'BF_BITNESS']
okdict = {}
@@ -229,6 +230,7 @@ def read_opts(env, cfg, args):
('BF_PYTHON_LIBPATH', 'Library path', ''),
('BF_PYTHON_LINKFLAGS', 'Python link flags', ''),
(BoolVariable('WITH_BF_STATICPYTHON', 'Staticly link to python', False)),
(BoolVariable('WITH_OSX_STATICPYTHON', 'Staticly link to python', True)),
('BF_PYTHON_ABI_FLAGS', 'Python ABI flags (suffix in library version: m, mu, etc)', ''),
(BoolVariable('BF_NO_ELBEEM', 'Disable Fluid Sim', False)),
@@ -290,6 +292,7 @@ def read_opts(env, cfg, args):
(BoolVariable('WITH_BF_FFMPEG', 'Use FFMPEG if true', False)),
('BF_FFMPEG', 'FFMPEG base path', ''),
('BF_FFMPEG_LIB', 'FFMPEG library', ''),
('BF_FFMPEG_DLL', 'FFMPEG dll libraries to be installed', ''),
('BF_FFMPEG_EXTRA', 'FFMPEG flags that must be preserved', ''),
('BF_FFMPEG_INC', 'FFMPEG includes', ''),
@@ -385,6 +388,7 @@ def read_opts(env, cfg, args):
('BF_OPENMP_INC', 'Path to OpenMP includes (used when cross-compiling with older versions of WinGW)', ''),
('BF_OPENMP_LIBPATH', 'Path to OpenMP libraries (used when cross-compiling with older versions of WinGW)', ''),
(BoolVariable('WITH_GHOST_COCOA', 'Use Cocoa-framework if true', False)),
(BoolVariable('WITH_GHOST_SDL', 'Enable building blender against SDL for windowing rather then the native APIs', False)),
(BoolVariable('USE_QTKIT', 'Use QTKIT if true', False)),
(BoolVariable('WITH_BF_QUICKTIME', 'Use QuickTime if true', False)),
@@ -435,6 +439,14 @@ def read_opts(env, cfg, args):
(BoolVariable('WITH_BF_PLAYER', 'Build blenderplayer if true', False)),
(BoolVariable('WITH_BF_NOBLENDER', 'Do not build blender if true', False)),
(BoolVariable('WITH_BF_3DMOUSE', 'Build blender with support of 3D mouses', False)),
(BoolVariable('WITH_BF_STATIC3DMOUSE', 'Staticly link to 3d mouse library', False)),
('BF_3DMOUSE', '3d mouse library base path', ''),
('BF_3DMOUSE_INC', '3d mouse library include path', ''),
('BF_3DMOUSE_LIB', '3d mouse library', ''),
('BF_3DMOUSE_LIBPATH', '3d mouse library path', ''),
('BF_3DMOUSE_LIB_STATIC', '3d mouse static library', ''),
('CFLAGS', 'C only flags', []),
('CCFLAGS', 'Generic C and C++ flags', []),
('CXXFLAGS', 'C++ only flags', []),
@@ -451,6 +463,8 @@ def read_opts(env, cfg, args):
('LLIBS', 'Platform libs', []),
('PLATFORM_LINKFLAGS', 'Platform linkflags', []),
('MACOSX_ARCHITECTURE', 'python_arch.zip select', ''),
('MACOSX_SDK_CHECK', 'detect available OSX sdk`s', ''),
('XCODE_CUR_VER', 'detect XCode version', ''),
(BoolVariable('BF_PROFILE', 'Add profiling information if true', False)),
('BF_PROFILE_CFLAGS', 'C only profiling flags', []),
@@ -555,7 +569,7 @@ def buildslave(target=None, source=None, env=None):
extension = '.tar.bz2'
platform = env['OURPLATFORM'].split('-')[0]
if platform == 'linux2':
if platform == 'linux':
import platform
bitness = platform.architecture()[0]

View File

@@ -0,0 +1,477 @@
#! /usr/bin/env python3
# ***** 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.
#
# ***** END GPL LICENCE BLOCK *****
######################################################
#
# Name:
# dna.py
#
# Description:
# Creates a browsable DNA output to HTML.
#
# Author:
# Jeroen Bakker
#
# Version:
# v0.1 (12-05-2009) - migration of original source code to python.
# Added code to support blender 2.5 branch
# v0.2 (25-05-2009) - integrated with BlendFileReader.py
#
# Input:
# blender build executable
#
# Output:
# dna.html
# dna.css (will only be created when not existing)
#
# Startup:
# ./blender -P BlendFileDnaExporter.py
#
# Process:
# 1: write blend file with SDNA info
# 2: read blend header from blend file
# 3: seek DNA1 file-block
# 4: read dna record from blend file
# 5: close and eventually delete temp blend file
# 6: export dna to html and css
# 7: quit blender
#
######################################################
import struct
import sys
import getopt # command line arguments handling
from string import Template # strings completion
# logs
import logging
log = logging.getLogger("BlendFileDnaExporter")
if '--dna-debug' in sys.argv:
logging.basicConfig(level=logging.DEBUG)
else:
logging.basicConfig(level=logging.INFO)
class DNACatalogHTML:
'''
DNACatalog is a catalog of all information in the DNA1 file-block
'''
def __init__(self, catalog, bpy_module = None):
self.Catalog = catalog
self.bpy = bpy_module
def WriteToHTML(self, handle):
dna_html_template = """
<!DOCTYPE html PUBLIC -//W3C//DTD HTML 4.01 Transitional//EN http://www.w3.org/TR/html4/loose.dtd>
<html>
<head>
<link rel="stylesheet" type="text/css" href="dna.css" media="screen, print" />
<meta http-equiv="Content-Type" content="text/html"; charset="ISO-8859-1" />
<title>The mystery of the blend</title>
</head>
<body>
<div class=title>
Blender ${version}<br/>
Internal SDNA structures
</div>
Architecture: ${bitness} ${endianness}<br/>
Build revision: <a href="https://svn.blender.org/svnroot/bf-blender/!svn/bc/${revision}/trunk/">${revision}</a><br/>
File format reference: <a href="mystery_of_the_blend.html">The mystery of the blend</a> by Jeroen Bakker<br/>
<h1>Index of blender structures</h1>
<ul class=multicolumn>
${structs_list}
</ul>
${structs_content}
</body>
</html>"""
header = self.Catalog.Header
bpy = self.bpy
# ${version} and ${revision}
if bpy:
version = '.'.join(map(str, bpy.app.version))
revision = bpy.app.build_revision[:-1]
else:
version = str(header.Version)
revision = 'Unknown'
# ${bitness}
if header.PointerSize == 8:
bitness = '64 bit'
else:
bitness = '32 bit'
# ${endianness}
if header.LittleEndianness:
endianess= 'Little endianness'
else:
endianess= 'Big endianness'
# ${structs_list}
log.debug("Creating structs index")
structs_list = ''
list_item = '<li class="multicolumn">({0}) <a href="#{1}">{1}</a></li>\n'
structureIndex = 0
for structure in self.Catalog.Structs:
structs_list += list_item.format(structureIndex, structure.Type.Name)
structureIndex+=1
# ${structs_content}
log.debug("Creating structs content")
structs_content = ''
for structure in self.Catalog.Structs:
log.debug(structure.Type.Name)
structs_content += self.Structure(structure)
d = dict(
version = version,
revision = revision,
bitness = bitness,
endianness = endianess,
structs_list = structs_list,
structs_content = structs_content
)
dna_html = Template(dna_html_template).substitute(d)
dna_html = self.format(dna_html)
handle.write(dna_html)
def Structure(self, structure):
struct_table_template = """
<table><a name="${struct_name}"></a>
<caption><a href="#${struct_name}">${struct_name}</a></caption>
<thead>
<tr>
<th>reference</th>
<th>structure</th>
<th>type</th>
<th>name</th>
<th>offset</th>
<th>size</th>
</tr>
</thead>
<tbody>
${fields}
</tbody>
</table>
<label>Total size: ${size} bytes</label><br/>
<label>(<a href="#top">top</a>)</label><br/>"""
d = dict(
struct_name = structure.Type.Name,
fields = self.StructureFields(structure, None, 0),
size = str(structure.Type.Size)
)
struct_table = Template(struct_table_template).substitute(d)
return struct_table
def StructureFields(self, structure, parentReference, offset):
fields = ''
for field in structure.Fields:
fields += self.StructureField(field, structure, parentReference, offset)
offset += field.Size(self.Catalog.Header)
return fields
def StructureField(self, field, structure, parentReference, offset):
structure_field_template = """
<tr>
<td>${reference}</td>
<td>${struct}</td>
<td>${type}</td>
<td>${name}</td>
<td>${offset}</td>
<td>${size}</td>
</tr>"""
if field.Type.Structure == None or field.Name.IsPointer():
# ${reference}
reference = field.Name.AsReference(parentReference)
# ${struct}
if parentReference != None:
struct = '<a href="#{0}">{0}</a>'.format(structure.Type.Name)
else:
struct = structure.Type.Name
# ${type}
type = field.Type.Name
# ${name}
name = field.Name.Name
# ${offset}
# offset already set
# ${size}
size = field.Size(self.Catalog.Header)
d = dict(
reference = reference,
struct = struct,
type = type,
name = name,
offset = offset,
size = size
)
structure_field = Template(structure_field_template).substitute(d)
elif field.Type.Structure != None:
reference = field.Name.AsReference(parentReference)
structure_field = self.StructureFields(field.Type.Structure, reference, offset)
return structure_field
def indent(self, input, dent, startswith = ''):
output = ''
if dent < 0:
for line in input.split('\n'):
dent = abs(dent)
output += line[dent:] + '\n' # unindent of a desired amount
elif dent == 0:
for line in input.split('\n'):
output += line.lstrip() + '\n' # remove indentation completely
elif dent > 0:
for line in input.split('\n'):
output += ' '* dent + line + '\n'
return output
def format(self, input):
diff = {
'\n<!DOCTYPE':'<!DOCTYPE',
'\n</ul>' :'</ul>',
'<a name' :'\n<a name',
'<tr>\n' :'<tr>',
'<tr>' :' <tr>',
'</th>\n' :'</th>',
'</td>\n' :'</td>',
'<tbody>\n' :'<tbody>'
}
output = self.indent(input, 0)
for key, value in diff.items():
output = output.replace(key, value)
return output
def WriteToCSS(self, handle):
'''
Write the Cascading stylesheet template to the handle
It is expected that the handle is a Filehandle
'''
css = """
@CHARSET "ISO-8859-1";
body {
font-family: verdana;
font-size: small;
}
div.title {
font-size: large;
text-align: center;
}
h1 {
page-break-before: always;
}
h1, h2 {
background-color: #D3D3D3;
color:#404040;
margin-right: 3%;
padding-left: 40px;
}
h1:hover{
background-color: #EBEBEB;
}
h3 {
padding-left: 40px;
}
table {
border-width: 1px;
border-style: solid;
border-color: #000000;
border-collapse: collapse;
width: 94%;
margin: 20px 3% 10px;
}
caption {
margin-bottom: 5px;
}
th {
background-color: #000000;
color:#ffffff;
padding-left:5px;
padding-right:5px;
}
tr {
}
td {
border-width: 1px;
border-style: solid;
border-color: #a0a0a0;
padding-left:5px;
padding-right:5px;
}
label {
float:right;
margin-right: 3%;
}
ul.multicolumn {
list-style:none;
float:left;
padding-right:0px;
margin-right:0px;
}
li.multicolumn {
float:left;
width:200px;
margin-right:0px;
}
a {
color:#a000a0;
text-decoration:none;
}
a:hover {
color:#a000a0;
text-decoration:underline;
}
"""
css = self.indent(css, 0)
handle.write(css)
def usage():
print("\nUsage: \n\tblender2.5 -b -P BlendFileDnaExporter_25.py [-- [options]]")
print("Options:")
print("\t--dna-keep-blend: doesn't delete the produced blend file DNA export to html")
print("\t--dna-debug: sets the logging level to DEBUG (lots of additional info)")
print("\t--dna-versioned saves version informations in the html and blend filenames")
print("\t--dna-overwrite-css overwrite dna.css, useful when modifying css in the script")
print("Examples:")
print("\tdefault: % blender2.5 -b -P BlendFileDnaExporter_25.py")
print("\twith options: % blender2.5 -b -P BlendFileDnaExporter_25.py -- --dna-keep-blend --dna-debug\n")
######################################################
# Main
######################################################
def main():
import os, os.path
try:
bpy = __import__('bpy')
# Files
if '--dna-versioned' in sys.argv:
blender_version = '_'.join(map(str, bpy.app.version))
filename = 'dna-{0}-{1}_endian-{2}-r{3}'.format(sys.arch, sys.byteorder, blender_version, bpy.app.build_revision[2:-1])
else:
filename = 'dna'
dir = os.path.dirname(__file__)
Path_Blend = os.path.join(dir, filename + '.blend') # temporary blend file
Path_HTML = os.path.join(dir, filename + '.html') # output html file
Path_CSS = os.path.join(dir, 'dna.css') # output css file
# create a blend file for dna parsing
if not os.path.exists(Path_Blend):
log.info("1: write temp blend file with SDNA info")
log.info(" saving to: " + Path_Blend)
try:
bpy.ops.wm.save_as_mainfile(filepath = Path_Blend, copy = True, compress = False)
except:
log.error("Filename {0} does not exist and can't be created... quitting".format(Path_Blend))
return
else:
log.info("1: found blend file with SDNA info")
log.info(" " + Path_Blend)
# read blend header from blend file
log.info("2: read file:")
if not dir in sys.path:
sys.path.append(dir)
import BlendFileReader
handle = BlendFileReader.openBlendFile(Path_Blend)
blendfile = BlendFileReader.BlendFile(handle)
catalog = DNACatalogHTML(blendfile.Catalog, bpy)
# close temp file
handle.close()
# deleting or not?
if '--dna-keep-blend' in sys.argv:
# keep the blend, useful for studying hexdumps
log.info("5: closing blend file:")
log.info(" {0}".format(Path_Blend))
else:
# delete the blend
log.info("5: close and delete temp blend:")
log.info(" {0}".format(Path_Blend))
os.remove(Path_Blend)
# export dna to xhtml
log.info("6: export sdna to xhtml file")
handleHTML = open(Path_HTML, "w")
catalog.WriteToHTML(handleHTML)
handleHTML.close()
# only write the css when doesn't exist or at explicit request
if not os.path.exists(Path_CSS) or '--dna-overwrite-css' in sys.argv:
handleCSS = open(Path_CSS, "w")
catalog.WriteToCSS(handleCSS)
handleCSS.close()
# quit blender
if not bpy.app.background:
log.info("7: quit blender")
bpy.ops.wm.exit_blender()
except ImportError:
log.warning(" skipping, not running in Blender")
usage()
sys.exit(2)
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,446 @@
#! /usr/bin/env python3
# ***** 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.
#
# ***** END GPL LICENCE BLOCK *****
######################################################
# Importing modules
######################################################
import os
import struct
import gzip
import tempfile
import logging
log = logging.getLogger("BlendFileReader")
######################################################
# module global routines
######################################################
def ReadString(handle, length):
'''
ReadString reads a String of given length or a zero terminating String
from a file handle
'''
if length != 0:
return handle.read(length).decode()
else:
# length == 0 means we want a zero terminating string
result = ""
s = ReadString(handle, 1)
while s!="\0":
result += s
s = ReadString(handle, 1)
return result
def Read(type, handle, fileheader):
'''
Reads the chosen type from a file handle
'''
def unpacked_bytes(type_char, size):
return struct.unpack(fileheader.StructPre + type_char, handle.read(size))[0]
if type == 'ushort':
return unpacked_bytes("H", 2) # unsigned short
elif type == 'short':
return unpacked_bytes("h", 2) # short
elif type == 'uint':
return unpacked_bytes("I", 4) # unsigned int
elif type == 'int':
return unpacked_bytes("i", 4) # int
elif type == 'float':
return unpacked_bytes("f", 4) # float
elif type == 'ulong':
return unpacked_bytes("Q", 8) # unsigned long
elif type == 'pointer':
# The pointersize is given by the header (BlendFileHeader).
if fileheader.PointerSize == 4:
return Read('uint', handle, fileheader)
if fileheader.PointerSize == 8:
return Read('ulong', handle, fileheader)
def openBlendFile(filename):
'''
Open a filename, determine if the file is compressed and returns a handle
'''
handle = open(filename, 'rb')
magic = ReadString(handle, 7)
if magic in ("BLENDER", "BULLETf"):
log.debug("normal blendfile detected")
handle.seek(0, os.SEEK_SET)
return handle
else:
log.debug("gzip blendfile detected?")
handle.close()
log.debug("decompressing started")
fs = gzip.open(filename, "rb")
handle = tempfile.TemporaryFile()
data = fs.read(1024*1024)
while data:
handle.write(data)
data = fs.read(1024*1024)
log.debug("decompressing finished")
fs.close()
log.debug("resetting decompressed file")
handle.seek(0, os.SEEK_SET)
return handle
def Align(handle):
'''
Aligns the filehandle on 4 bytes
'''
offset = handle.tell()
trim = offset % 4
if trim != 0:
handle.seek(4-trim, os.SEEK_CUR)
######################################################
# module classes
######################################################
class BlendFile:
'''
Reads a blendfile and store the header, all the fileblocks, and catalogue
structs foound in the DNA fileblock
- BlendFile.Header (BlendFileHeader instance)
- BlendFile.Blocks (list of BlendFileBlock instances)
- BlendFile.Catalog (DNACatalog instance)
'''
def __init__(self, handle):
log.debug("initializing reading blend-file")
self.Header = BlendFileHeader(handle)
self.Blocks = []
fileblock = BlendFileBlock(handle, self)
found_dna_block = False
while not found_dna_block:
if fileblock.Header.Code in ("DNA1", "SDNA"):
self.Catalog = DNACatalog(self.Header, handle)
found_dna_block = True
else:
fileblock.Header.skip(handle)
self.Blocks.append(fileblock)
fileblock = BlendFileBlock(handle, self)
# appending last fileblock, "ENDB"
self.Blocks.append(fileblock)
# seems unused?
"""
def FindBlendFileBlocksWithCode(self, code):
#result = []
#for block in self.Blocks:
#if block.Header.Code.startswith(code) or block.Header.Code.endswith(code):
#result.append(block)
#return result
"""
class BlendFileHeader:
'''
BlendFileHeader allocates the first 12 bytes of a blend file.
It contains information about the hardware architecture.
Header example: BLENDER_v254
BlendFileHeader.Magic (str)
BlendFileHeader.PointerSize (int)
BlendFileHeader.LittleEndianness (bool)
BlendFileHeader.StructPre (str) see http://docs.python.org/py3k/library/struct.html#byte-order-size-and-alignment
BlendFileHeader.Version (int)
'''
def __init__(self, handle):
log.debug("reading blend-file-header")
self.Magic = ReadString(handle, 7)
log.debug(self.Magic)
pointersize = ReadString(handle, 1)
log.debug(pointersize)
if pointersize == "-":
self.PointerSize = 8
if pointersize == "_":
self.PointerSize = 4
endianness = ReadString(handle, 1)
log.debug(endianness)
if endianness == "v":
self.LittleEndianness = True
self.StructPre = "<"
if endianness == "V":
self.LittleEndianness = False
self.StructPre = ">"
version = ReadString(handle, 3)
log.debug(version)
self.Version = int(version)
log.debug("{0} {1} {2} {3}".format(self.Magic, self.PointerSize, self.LittleEndianness, version))
class BlendFileBlock:
'''
BlendFileBlock.File (BlendFile)
BlendFileBlock.Header (FileBlockHeader)
'''
def __init__(self, handle, blendfile):
self.File = blendfile
self.Header = FileBlockHeader(handle, blendfile.Header)
def Get(self, handle, path):
log.debug("find dna structure")
dnaIndex = self.Header.SDNAIndex
dnaStruct = self.File.Catalog.Structs[dnaIndex]
log.debug("found " + dnaStruct.Type.Name)
handle.seek(self.Header.FileOffset, os.SEEK_SET)
return dnaStruct.GetField(self.File.Header, handle, path)
class FileBlockHeader:
'''
FileBlockHeader contains the information in a file-block-header.
The class is needed for searching to the correct file-block (containing Code: DNA1)
Code (str)
Size (int)
OldAddress (pointer)
SDNAIndex (int)
Count (int)
FileOffset (= file pointer of datablock)
'''
def __init__(self, handle, fileheader):
self.Code = ReadString(handle, 4).strip()
if self.Code != "ENDB":
self.Size = Read('uint', handle, fileheader)
self.OldAddress = Read('pointer', handle, fileheader)
self.SDNAIndex = Read('uint', handle, fileheader)
self.Count = Read('uint', handle, fileheader)
self.FileOffset = handle.tell()
else:
self.Size = Read('uint', handle, fileheader)
self.OldAddress = 0
self.SDNAIndex = 0
self.Count = 0
self.FileOffset = handle.tell()
#self.Code += ' ' * (4 - len(self.Code))
log.debug("found blend-file-block-fileheader {0} {1}".format(self.Code, self.FileOffset))
def skip(self, handle):
handle.read(self.Size)
class DNACatalog:
'''
DNACatalog is a catalog of all information in the DNA1 file-block
Header = None
Names = None
Types = None
Structs = None
'''
def __init__(self, fileheader, handle):
log.debug("building DNA catalog")
self.Names=[]
self.Types=[]
self.Structs=[]
self.Header = fileheader
SDNA = ReadString(handle, 4)
# names
NAME = ReadString(handle, 4)
numberOfNames = Read('uint', handle, fileheader)
log.debug("building #{0} names".format(numberOfNames))
for i in range(numberOfNames):
name = ReadString(handle,0)
self.Names.append(DNAName(name))
Align(handle)
# types
TYPE = ReadString(handle, 4)
numberOfTypes = Read('uint', handle, fileheader)
log.debug("building #{0} types".format(numberOfTypes))
for i in range(numberOfTypes):
type = ReadString(handle,0)
self.Types.append(DNAType(type))
Align(handle)
# type lengths
TLEN = ReadString(handle, 4)
log.debug("building #{0} type-lengths".format(numberOfTypes))
for i in range(numberOfTypes):
length = Read('ushort', handle, fileheader)
self.Types[i].Size = length
Align(handle)
# structs
STRC = ReadString(handle, 4)
numberOfStructures = Read('uint', handle, fileheader)
log.debug("building #{0} structures".format(numberOfStructures))
for structureIndex in range(numberOfStructures):
type = Read('ushort', handle, fileheader)
Type = self.Types[type]
structure = DNAStructure(Type)
self.Structs.append(structure)
numberOfFields = Read('ushort', handle, fileheader)
for fieldIndex in range(numberOfFields):
fTypeIndex = Read('ushort', handle, fileheader)
fNameIndex = Read('ushort', handle, fileheader)
fType = self.Types[fTypeIndex]
fName = self.Names[fNameIndex]
structure.Fields.append(DNAField(fType, fName))
class DNAName:
'''
DNAName is a C-type name stored in the DNA.
Name = str
'''
def __init__(self, name):
self.Name = name
def AsReference(self, parent):
if parent == None:
result = ""
else:
result = parent+"."
result = result + self.ShortName()
return result
def ShortName(self):
result = self.Name;
result = result.replace("*", "")
result = result.replace("(", "")
result = result.replace(")", "")
Index = result.find("[")
if Index != -1:
result = result[0:Index]
return result
def IsPointer(self):
return self.Name.find("*")>-1
def IsMethodPointer(self):
return self.Name.find("(*")>-1
def ArraySize(self):
result = 1
Temp = self.Name
Index = Temp.find("[")
while Index != -1:
Index2 = Temp.find("]")
result*=int(Temp[Index+1:Index2])
Temp = Temp[Index2+1:]
Index = Temp.find("[")
return result
class DNAType:
'''
DNAType is a C-type stored in the DNA
Name = str
Size = int
Structure = DNAStructure
'''
def __init__(self, aName):
self.Name = aName
self.Structure=None
class DNAStructure:
'''
DNAType is a C-type structure stored in the DNA
Type = DNAType
Fields = [DNAField]
'''
def __init__(self, aType):
self.Type = aType
self.Type.Structure = self
self.Fields=[]
def GetField(self, header, handle, path):
splitted = path.partition(".")
name = splitted[0]
rest = splitted[2]
offset = 0;
for field in self.Fields:
if field.Name.ShortName() == name:
log.debug("found "+name+"@"+str(offset))
handle.seek(offset, os.SEEK_CUR)
return field.DecodeField(header, handle, rest)
else:
offset += field.Size(header)
log.debug("error did not find "+path)
return None
class DNAField:
'''
DNAField is a coupled DNAType and DNAName.
Type = DNAType
Name = DNAName
'''
def __init__(self, aType, aName):
self.Type = aType
self.Name = aName
def Size(self, header):
if self.Name.IsPointer() or self.Name.IsMethodPointer():
return header.PointerSize*self.Name.ArraySize()
else:
return self.Type.Size*self.Name.ArraySize()
def DecodeField(self, header, handle, path):
if path == "":
if self.Name.IsPointer():
return Read('pointer', handle, header)
if self.Type.Name=="int":
return Read('int', handle, header)
if self.Type.Name=="short":
return Read('short', handle, header)
if self.Type.Name=="float":
return Read('float', handle, header)
if self.Type.Name=="char":
return ReadString(handle, self.Name.ArraySize())
else:
return self.Type.Structure.GetField(header, handle, path)

View File

@@ -0,0 +1,29 @@
To inspect the blend-file-format used by a certain version of blender 2.5x,
navigate to this folder and run this command:
blender2.5 -b -P BlendFileDnaExporter_25.py
where "blender2.5" is your blender executable or a symlink to it.
This creates a temporary dna.blend to be inspected and it produces two new files:
* dna.html: the list of all the structures saved in a blend file with the blender2.5
executable you have used. If you enable build informations when you build blender,
the dna.html file will also show which svn revision the html refers to.
* dna.css: the css for the html above
Below you have the help message with a list of options you can use.
Usage:
blender2.5 -b -P BlendFileDnaExporter_25.py [-- [options]]
Options:
--dna-keep-blend: doesn't delete the produced blend file DNA export to html
--dna-debug: sets the logging level to DEBUG (lots of additional info)
--dna-versioned saves version informations in the html and blend filenames
--dna-overwrite-css overwrite dna.css, useful when modifying css in the script
Examples:
default: % blender2.5 -b -P BlendFileDnaExporter_25.py
with options: % blender2.5 -b -P BlendFileDnaExporter_25.py -- --dna-keep-blend --dna-debug

View File

@@ -0,0 +1,204 @@
@CHARSET "ISO-8859-1";
table {
border-width: 1px;
border-style: solid;
border-color: #000000;
border-collapse: collapse;
width: 94%;
margin: 10px 3%;
}
DIV.title {
font-size: 30px;
font-weight: bold;
text-align: center
}
DIV.subtitle {
font-size: large;
text-align: center
}
DIV.contact {
margin:30px 3%;
}
@media print {
DIV.contact {
margin-top: 300px;
}
DIV.title {
margin-top: 400px;
}
}
label {
font-weight: bold;
width: 100px;
float: left;
}
label:after {
content: ":";
}
TH {
background-color: #000000;
color: #ffffff;
padding-left: 5px;
padding-right: 5px;
}
TR {
}
TD {
border-width: 1px;
border-style: solid;
border-color: #a0a0a0;
padding-left: 5px;
padding-right: 5px;
}
BODY {
font-family: verdana;
font-size: small;
}
H1 {
page-break-before: always;
}
H1, H2, H3, H4 {
margin-top: 30px;
margin-right: 3%;
padding: 3px 3%;
color: #404040;
cursor: pointer;
}
H1, H2 {
background-color: #D3D3D3;
}
H3, H4 {
padding-top: 5px;
padding-bottom: 5px;
}
H1:hover, H2:hover, H3:hover, H4:hover {
background-color: #EBEBEB;
}
CODE.evidence {
font-size:larger
}
CODE.block {
color: #000000;
background-color: #DDDC75;
margin: 10px 0;
padding: 5px;
border-width: 1px;
border-style: dotted;
border-color: #000000;
white-space: pre;
display: block;
font-size: 2 em;
}
ul {
margin: 10px 3%;
}
li {
margin: 0 -15px;
}
ul.multicolumn {
list-style: none;
float: left;
padding-right: 0px;
margin-right: 0px;
}
li.multicolumn {
float: left;
width: 200px;
margin-right: 0px;
}
@media screen {
p {
margin: 10px 3%;
line-height: 130%;
}
}
span.fade {
color: gray;
}
span.header {
color: green;
}
span.header-greyed {
color: #4CBE4B;
}
span.data {
color: blue;
}
span.data-greyed {
color: #5D99C4;
}
span.descr {
color: red;
}
div.box {
margin: 15px 3%;
border-style: dotted;
border-width: 1px;
}
div.box-solid {
margin: 15px 3%;
border-style: solid;
border-width: 1px;
}
p.box-title {
font-style: italic;
font-size: 110%;
cursor: pointer;
}
p.box-title:hover {
background-color: #EBEBEB;
}
p.code {
font-family: "Courier New", Courier, monospace;
}
a {
color: #a000a0;
text-decoration: none;
}
a:hover {
color: #a000a0;
text-decoration: underline;
}
td.skip {
color: #808080;
padding-top: 10px;
padding-bottom: 10px;
text-align: center;
}

View File

@@ -0,0 +1,835 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<link rel="stylesheet" type="text/css" href="mystery_of_the_blend.css" media="screen, print">
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>The mystery of the blend</title>
</head>
<body>
<div class="title">The mystery of the blend</div>
<div class="subtitle">The blender file-format explained</div>
<div class="contact">
<label>Author</label> Jeroen Bakker<br>
<label>Email</label> <a href="mailto:j.bakker@atmind.nl">j.bakker@atmind.nl</a><br>
<label>Website</label> <a href="http://www.atmind.nl/blender/">http://www.atmind.nl/blender</a><br>
<label>Version</label> 06-10-2010<br>
</div>
<a name="introduction" href="#introduction" ><h2>Introduction</h2></a>
</a>
<p>In this article I will describe the
blend-file-format with a request to tool-makers to support blend-file.
</p>
<p>First I'll describe how Blender works with blend-files. You'll notice
why the blend-file-format is not that well documented, as from
Blender's perspective this is not needed.
We look at the global file-structure of a blend-file (the file-header
and file-blocks).
After this is explained, we go deeper to the core of the blend-file, the
DNA-structures. They hold the blue-prints of the blend-file and the key
asset of understanding blend-files.
When that's done we can use these DNA-structures to read information
from elsewhere in the blend-file.
</p>
<p>
In this article we'll be using the default blend-file from Blender 2.54,
with the goal to read the output resolution from the Scene.
The article is written to be programming language independent and I've
setup a web-site for support.
</p>
<a name="loading-and-saving-in-blender" href="#loading-and-saving-in-blender">
<h2>Loading and saving in Blender</h2>
</a>
<p>
Loading and saving in Blender is very fast and Blender is known to
have excellent downward and upward compatibility. Ton Roosendaal
demonstrated that in December 2008 by loading a 1.0 blend-file using
Blender 2.48a [ref: <a href="http://www.blendernation.com/2008/12/01/blender-dna-rna-and-backward-compatibility/">http://www.blendernation.com/2008/12/01/blender-dna-rna-and-backward-compatibility/</a>].
</p>
<p>
Saving complex scenes in Blender is done within seconds. Blender
achieves this by saving data in memory to disk without any
transformations or translations. Blender only adds file-block-headers to
this data. A file-block-header contains clues on how to interpret the
data. After the data, all internally Blender structures are stored.
These structures will act as blue-prints when Blender loads the file.
Blend-files can be different when stored on different hardware platforms
or Blender releases. There is no effort taken to make blend-files
binary the same. Blender creates the blend-files in this manner since
release 1.0. Backward and upwards compatibility is not implemented when
saving the file, this is done during loading.
</p>
<p>
When Blender loads a blend-file, the DNA-structures are read first.
Blender creates a catalog of these DNA-structures. Blender uses this
catalog together with the data in the file, the internal Blender
structures of the Blender release you're using and a lot of
transformation and translation logic to implement the backward and
upward compatibility. In the source code of blender there is actually
logic which can transform and translate every structure used by a
Blender release to the one of the release you're using [ref: <a href="http://download.blender.org/source/blender-2.48a.tar.gz">http://download.blender.org/source/blender-2.48a.tar.gz</a>
<a href="https://svn.blender.org/svnroot/bf-blender/tags/blender-2.48-release/source/blender/blenloader/intern/readfile.c">blender/blenloader/intern/readfile.c</a> lines
4946-7960]. The more difference between releases the more logic is
executed.
</p>
<p>
The blend-file-format is not well documented, as it does not differ from
internally used structures and the file can really explain itself.
</p>
<a name="global-file-structure" href="#global-file-structure">
<h2>Global file-structure</h2>
</a>
<p>
This section explains how the global file-structure can be read.
</p>
<ul>
<li>A blend-file always start with the <b>file-header</b></li>
<li>After the file-header, follows a list of <b>file-blocks</b> (the default blend file of Blender 2.48 contains more than 400 of these file-blocks).</li>
<li>Each file-block has a <b>file-block header</b> and <b>file-block data</b></li>
<li>At the end of the blend-file there is a section called "<a href="#structure-DNA" style="font-weight:bold">Structure DNA</a>", which lists all the internal structures of the Blender release the file was created in</li>
<li>The blend-file ends with a file-block called 'ENDB'</li>
</ul>
<!-- file scheme -->
<div class="box-solid" style="width:20%; margin-left:35%; font-size:0.8em;">
<p class="code"><b>File.blend</b></p>
<div class="box"><p class="code">File-header</p></div>
<div class="box-solid"><p class="code">File-block</p>
<div class="box"><p class="code">Header</p></div>
<div class="box"><p class="code">Data</p></div>
</div>
<div class="box" style="border-style:dashed"><p class="code">File-block</p></div>
<div class="box" style="border-style:dashed"><p class="code">File-block</p></div>
<div class="box-solid"><p class="code">File-block 'Structure DNA'</p>
<div class="box"><p class="code">Header ('DNA1')</p></div>
<div class="box-solid">
<p class="code">Data ('SDNA')</p>
<div class="box">
<p class="code">Names ('NAME')</p>
</div>
<div class="box">
<p class="code">Types ('TYPE')</p>
</div>
<div class="box">
<p class="code">Lengths ('TLEN')</p>
</div>
<div class="box">
<p class="code">Structures ('STRC')</p>
</div>
</div>
</div>
<div class="box-solid"><p class="code">File-Block 'ENDB'</p></div>
</div><!-- end of file scheme -->
<a name="file-header" href="#file-header">
<h3>File-Header</h3>
</a>
<p>
The first 12 bytes of every blend-file is the file-header. The
file-header has information on Blender (version-number) and the PC the
blend-file was saved on (pointer-size and endianness). This is required
as all data inside the blend-file is ordered in that way, because no
translation or transformation is done during saving.
The next table describes the information in the file-header.
</p>
<table>
<caption>File-header</caption>
<thead>
<tr><th>reference</th>
<th>structure</th>
<th>type</th>
<th>offset</th>
<th>size</th></tr>
</thead>
<tbody>
<tr><td>identifier</td>
<td>char[7]</td>
<td>File identifier (always 'BLENDER')</td>
<td>0</td>
<td>7</td></tr>
<tr><td>pointer-size</td>
<td>char</td>
<td>Size of a pointer; all pointers in the file are stored in this format. '_' means 4 bytes or 32 bit and '-' means 8 bytes or 64 bits.</td>
<td>7</td>
<td>1</td></tr>
<tr><td>endianness</td>
<td>char</td>
<td>Type of byte ordering used; 'v' means little endian and 'V' means big endian.</td>
<td>8</td>
<td>1</td></tr>
<tr><td>version-number</td>
<td>char[3]</td>
<td>Version of Blender the file was created in; '254' means version 2.54</td>
<td>9</td>
<td>3</td></tr>
</tbody>
</table>
<p>
<a href="http://en.wikipedia.org/wiki/Endianness">Endianness</a> addresses the way values are ordered in a sequence of bytes(see the <a href="#example-endianess">example</a> below):
</p>
<ul>
<li>in a big endian ordering, the largest part of the value is placed on the first byte and
the lowest part of the value is placed on the last byte,</li>
<li>in a little endian ordering, largest part of the value is placed on the last byte
and the smallest part of the value is placed on the first byte.</li>
</ul>
<p>
Nowadays, little-endian is the most commonly used.
</p>
<a name="example-endianess"></a>
<div class="box">
<p onclick="location.href='#example-endianess'" class="box-title">
Endianess Example
</p>
<p>
Writing the integer <code class="evidence">0x4A3B2C1Dh</code>, will be ordered:
<ul>
<li>in big endian as <code class="evidence">0x4Ah</code>, <code class="evidence">0x3Bh</code>, <code class="evidence">0x2Ch</code>, <code class="evidence">0x1Dh</code></li>
<li>in little endian as <code class="evidence">0x1Dh</code>, <code class="evidence">0x2Ch</code>, <code class="evidence">0x3Bh</code>, <code class="evidence">0x4Ah</code></li>
</ul>
</p>
</div>
<p>
Blender supports little-endian and big-endian.<br>
This means that when the endianness
is different between the blend-file and the PC your using, Blender changes it to the byte ordering
of your PC.
</p>
<a name="example-file-header"></a>
<div class="box">
<p onclick="location.href='#example-file-header'" class="box-title">
File-header Example
</p>
<p>
This hex-dump describes a file-header created with <code>blender</code> <code>2.54.0</code> on <code>little-endian</code> hardware with a <code>32 bits</code> pointer length.
<code class="block"> <span class="descr">pointer-size version-number
| |</span>
0000 0000: [42 4C 45 4E 44 45 52] [5F] [76] [32 35 34] BLENDER_v254 <span class="descr">
| |
identifier endianness</span></code>
</p>
</div>
<a name="file-blocks" href="#file-blocks"><h3>File-blocks</h3></a>
<p>
File-blocks contain a "<a href="#file-block-header">file-block header</a>" and "file-block data".
</p>
<a name="file-block-header" href="#file-block-header"><h3>File-block headers</h3></a>
<p>
The file-block-header describes:
</p>
<ul>
<li>the type of information stored in the
file-block</li>
<li>the total length of the data</li>
<li>the old memory
pointer at the moment the data was written to disk</li>
<li>the number of items of this information</li>
</ul>
<p>
As we can see below, depending on the pointer-size stored in the file-header, a file-block-header
can be 20 or 24 bytes long, hence it is always aligned at 4 bytes.
</p>
<table>
<caption>File-block-header</caption>
<thead>
<tr>
<th>reference</th>
<th>structure</th>
<th>type</th>
<th>offset</th>
<th>size</th></tr></thead>
<tbody>
<tr><td>code</td>
<td>char[4]</td>
<td>File-block identifier</td>
<td>0</td>
<td>4</td></tr>
<tr><td>size</td>
<td>integer</td>
<td>Total length of the data after the file-block-header</td>
<td>4</td>
<td>4</td></tr>
<tr><td>old memory address</td>
<td>void*</td>
<td>Memory address the structure was located when written to disk</td>
<td>8</td>
<td>pointer-size (4/8)</td></tr>
<tr><td>SDNA index</td>
<td>integer</td>
<td>Index of the SDNA structure</td>
<td>8+pointer-size</td>
<td>4</td></tr>
<tr><td>count</td>
<td>integer</td>
<td>Number of structure located in this file-block</td>
<td>12+pointer-size</td>
<td>4</td></tr>
</tbody>
</table>
<p>
The above table describes how a file-block-header is structured:
</p>
<ul>
<li><code>Code</code> describes different types of file-blocks. The code determines with what logic the data must be read. <br>
These codes also allows fast finding of data like Library, Scenes, Object or Materials as they all have a specific code. </li>
<li><code>Size</code> contains the total length of data after the file-block-header.
After the data a new file-block starts. The last file-block in the file
has code 'ENDB'.</li>
<li><code>Old memory address</code> contains the memory address when the structure
was last stored. When loading the file the structures can be placed on
different memory addresses. Blender updates pointers to these structures
to the new memory addresses.</li>
<li><code>SDNA index</code> contains the index in the DNA structures to be used when
reading this file-block-data. <br>
More information about this subject will be explained in the <a href="#reading-scene-information">Reading scene information section</a>.</li>
<li><code>Count</code> tells how many elements of the specific SDNA structure can be found in the data.</li>
</ul>
<a name="example-file-block-header"></a>
<div class="box">
<p onclick="location.href='#example-file-block-header'" class="box-title">
Example
</p>
<p>
This hex-dump describes a File-block (= <span class="header">File-block header</span> + <span class="data">File-block data</span>) created with <code>blender</code> <code>2.54</code> on <code>little-endian</code> hardware with a <code>32 bits</code> pointer length.<br>
<code class="block"><span class="descr"> file-block
identifier='SC' data size=1404 old pointer SDNA index=150
| | | |</span>
0000 4420: <span class="header">[53 43 00 00] [7C 05 00 00] [68 34 FB 0B] [96 00 00 00]</span> SC.. `... ./.. ....
0000 4430: <span class="header">[01 00 00 00]</span> <span class="data">[xx xx xx xx xx xx xx xx xx xx xx xx</span> .... xxxx xxxx xxxx<span class="descr">
| |
count=1 file-block data (next 1404 bytes)</span>
</code>
</p>
<ul>
<li>The code <code>'SC'+0x00h</code> identifies that it is a Scene. </li>
<li>Size of the data is 1404 bytes (0x0000057Ch = 0x7Ch + 0x05h * 256 = 124 + 1280)</li>
<li>The old pointer is 0x0BFB3468h</li>
<li>The SDNA index is 150 (0x00000096h = 6 + 9 * 16 = 6 + 144)</li>
<li>The section contains a single scene (count = 1).</li>
</ul>
<p>
Before we can interpret the data of this file-block we first have to read the DNA structures in the file.
The section "<a href="#structure-DNA">Structure DNA</a>" will show how to do that.
</p>
</div>
<a name="structure-DNA" href="#structure-DNA"><h2>Structure DNA</h2></a>
<a name="DNA1-file-block" href="#DNA1-file-block"><h3>The DNA1 file-block</h3></a>
<p>
Structure DNA is stored in a file-block with code 'DNA1'. It can be just before the 'ENDB' file-block.
</p>
<p>
The 'DNA1' file-block contains all internal structures of the Blender release the
file was created in. <br>
These structure can be described as C-structures: they can hold fields, arrays and
pointers to other structures, just like a normal C-structure.
<p>
<code class="block">struct SceneRenderLayer {
struct SceneRenderLayer *next, *prev;
char name[32];
struct Material *mat_override;
struct Group *light_override;
unsigned int lay;
unsigned int lay_zmask;
int layflag;
int pad;
int passflag;
int pass_xor;
};
</code>
</p>
<p>
For example,a blend-file created with Blender 2.54 the 'DNA1' file-block is 57796 bytes long and contains 398 structures.
</p>
<a name="DNA1-file-block-header" href="#DNA1-file-block-header"><h3>DNA1 file-block-header</h3></a>
<p>
The DNA1 file-block header follows the same rules of any other file-block, see the example below.
</p>
<a name="example-DNA1-file-block-header"></a>
<div class="box">
<p onclick="location.href='#example-DNA1-file-block-header'" class="box-title">
Example
</p>
<p>
This hex-dump describes the file-block 'DNA1' header created with <code>blender</code> <code>2.54.0</code> on <code>little-endian</code> hardware with a <code>32 bits</code> pointer length.<br>
<code class="block"><span class="descr"> (file-block
identifier='DNA1') data size=57796 old pointer SDNA index=0
| | | |</span>
0004 B060 <span class="header">[44 4E 41 31] [C4 E1 00 00] [C8 00 84 0B] [00 00 00 00]</span> DNA1............
0004 B070 <span class="header">[01 00 00 00]</span> <span class="fade">[53 44 4E 41 4E 41 4D 45 CB 0B 00 00</span> ....<span class="fade">SDNANAME....</span><span class="descr">
| |
count=1 'DNA1' file-block data (next 57796 bytes)</span>
</code>
</p>
</div>
<a name="DNA1-file-block-data" href="#DNA1-file-block-data"><h3>DNA1 file-block data</h3></a>
<p>
The next section describes how this information is ordered in the <b>data</b> of the 'DNA1' file-block.
</p>
<table>
<caption>Structure of the DNA file-block-data</caption>
<thead>
<tr><th colspan="2">repeat condition</th>
<th>name</th>
<th>type</th>
<th>length</th>
<th>description</th></tr>
</thead>
<tbody>
<tr><td></td>
<td></td>
<td>identifier</td>
<td>char[4]</td>
<td>4</td>
<td>'SDNA'</td></tr>
<tr><td></td>
<td></td>
<td>name identifier</td>
<td>char[4]</td>
<td>4</td>
<td>'NAME'</td></tr>
<tr><td></td>
<td></td>
<td>#names</td>
<td>integer</td>
<td>4</td>
<td>Number of names follows</td></tr>
<tr><td>for(#names)</td>
<td></td>
<td>name</td>
<td>char[]</td>
<td>?</td>
<td>Zero terminating string of name, also contains pointer and simple array definitions (e.g. '*vertex[3]\0')</td></tr>
<tr><td></td>
<td></td>
<td>type identifier</td>
<td>char[4]</td>
<td>4</td>
<td>'TYPE' this field is aligned at 4 bytes</td></tr>
<tr><td></td>
<td></td>
<td>#types</td>
<td>integer</td>
<td>4</td>
<td>Number of types follows</td></tr>
<tr><td>for(#types)</td>
<td></td>
<td>type</td>
<td>char[]</td>
<td>?</td>
<td>Zero terminating string of type (e.g. 'int\0')</td></tr>
<tr><td></td>
<td></td>
<td>length identifier</td>
<td>char[4]</td>
<td>4</td>
<td>'TLEN' this field is aligned at 4 bytes</td></tr>
<tr><td>for(#types)</td>
<td></td>
<td>length</td>
<td>short</td>
<td>2</td>
<td>Length in bytes of type (e.g. 4)</td></tr>
<tr><td></td>
<td></td>
<td>structure identifier</td>
<td>char[4]</td>
<td>4</td>
<td>'STRC' this field is aligned at 4 bytes</td></tr>
<tr><td></td>
<td></td>
<td>#structures</td>
<td>integer</td>
<td>4</td>
<td>Number of structures follows</td></tr>
<tr><td>for(#structures)</td>
<td></td>
<td>structure type</td>
<td>short</td>
<td>2</td>
<td>Index in types containing the name of the structure</td></tr>
<tr><td>..</td>
<td></td>
<td>#fields</td>
<td>short</td>
<td>2</td>
<td>Number of fields in this structure</td></tr>
<tr><td>..</td>
<td>for(#field)</td>
<td>field type</td>
<td>short</td>
<td>2</td>
<td>Index in type</td></tr>
<tr><td>for end</td>
<td>for end</td>
<td>field name</td>
<td>short</td>
<td>2</td>
<td>Index in name</td></tr>
</tbody>
</table>
<p>
As you can see, the structures are stored in 4 arrays: names, types,
lengths and structures. Every structure also contains an array of
fields. A field is the combination of a type and a name. From this
information a catalog of all structures can be constructed.
The names are stored as how a C-developer defines them. This means that
the name also defines pointers and arrays.
(When a name starts with '*' it is used as a pointer. when the name
contains for example '[3]' it is used as a array of 3 long.)
In the types you'll find simple-types (like: 'integer', 'char',
'float'), but also complex-types like 'Scene' and 'MetaBall'.
'TLEN' part describes the length of the types. A 'char' is 1 byte, an
'integer' is 4 bytes and a 'Scene' is 1376 bytes long.
</p>
<div class="box">
<p class="box-title">
Note
</p>
<p>
All identifiers, are arrays of 4 chars, hence they are all aligned at 4 bytes.
</p>
</div>
<a name="example-DNA1-file-block-data"></a>
<div class="box">
<p onclick="location.href='#example-DNA1-file-block-data'" class="box-title">
Example
</p>
<p>
Created with <code>blender</code> <code>2.54.0</code> on <code>little-endian</code> hardware with a <code>32 bits</code> pointer length.
</p>
<a name="DNA1-data-array-names" href="#DNA1-data-array-names"><h4>The names array</h4></a>
<p>
The first names are: *next, *prev, *data, *first, *last, x, y, xmin, xmax, ymin, ymax, *pointer, group, val, val2, type, subtype, flag, name[32], ...
<code class="block"><span class="descr"> file-block-data identifier='SDNA' array-id='NAME' number of names=3019
| | |</span>
0004 B070 <span class="fade">01 00 00 00 [53 44 4E 41]</span><span class="data">[4E 41 4D 45] [CB 0B 00 00]</span> <span class="fade">....SDNA</span>NAME....
0004 B080 <span class="data">[2A 6E 65 78 74 00][2A 70 72 65 76 00] [2A 64 61 74</span> *next.*prev.*dat<span class="descr">
| | |
'*next\0' '*prev\0' '*dat'</span><span class="fade">
....
.... (3019 names)</span>
</code>
</p>
<div class="box">
<p class="box-title">
Note
</p>
<p>
While reading the DNA you'll will come across some strange
names like '(*doit)()'. These are method pointers and Blender updates
them to the correct methods.
</p>
</div>
<a name="DNA1-data-array-types" href="#DNA1-data-array-types"><h4>The types array</h4></a>
<p>
The first types are: char, uchar, short, ushort, int, long, ulong, float, double, void, Link, LinkData, ListBase, vec2s, vec2f, ...
<code class="block"><span class="descr"> array-id='TYPE'
|</span>
0005 2440 <span class="fade">6F 6C 64 5B 34 5D 5B 34 5D 00 00 00</span> [54 59 50 45] <span class="fade">old[4][4]...</span>TYPE
0005 2450 [C9 01 00 00] [63 68 61 72 00] [75 63 68 61 72 00][73 ....char.uchar.s<span class="descr">
| | | |
number of types=457 'char\0' 'uchar\0' 's'</span><span class="fade">
....
.... (457 types)</span>
</code>
</p>
<a name="DNA1-data-array-lengths" href="#DNA1-data-array-lengths"><h4>The lengths array</h4></a>
<p>
<code class="block"><span class="descr"> char uchar ushort short
array-id length length length length
'TLEN' 1 1 2 2</span>
0005 3AA0 <span class="fade">45 00 00 00</span> [54 4C 45 4E] [01 00] [01 00] [02 00] [02 00] <span class="fade">E...</span>TLEN........
<span class="fade">....</span>
0005 3AC0 [08 00] [04 00] [08 00] [10 00] [10 00] [14 00] [4C 00] [34 00] ............L.4.<span class="descr">
8 4 8
ListBase vec2s vec2f ... etc
length len length </span><span class="fade">
....
.... (457 lengths, same as number of types)</span>
</code>
</p>
<a name="DNA1-data-array-structures" href="#DNA1-data-array-structures"><h4>The structures array</h4></a>
<p>
<code class="block"><span class="descr"> array-id='STRC'
|</span>
0005 3E30 <span class="fade">40 00 38 00 60 00 00 00 00 00 00 00</span> [53 54 52 43] <span class="fade">@.8.`.......</span>STRC
0005 3E40 [8E 01 00 00] [0A 00] [02 00] [0A 00] [00 00] [0A 00] [01 00] ................<span class="descr">
398 10 2 10 0 10 0
number of index fields index index index index
structures in <a href="#DNA1-data-array-types">types</a> in <a href="#DNA1-data-array-types">types</a> in <a href="#DNA1-data-array-names">names</a> in <a href="#DNA1-data-array-types">types</a> in <a href="#DNA1-data-array-names">names</a></span><span class="fade">
' '----------------' '-----------------' '
' field 0 field 1 '
'--------------------------------------------------------'
structure 0
....
.... (398 structures, each one describeing own type, and type/name for each field)</span>
</code>
</p>
</div>
<p>
The DNA structures inside a Blender 2.48 blend-file can be found at <a href="http://www.atmind.nl/blender/blender-sdna.html">http://www.atmind.nl/blender/blender-sdna.html</a>.
If we understand the DNA part of the file it is now possible to read
information from other parts file-blocks. The next section will tell us
how.
</p>
<a name="reading-scene-information" href="#reading-scene-information"><h2>Reading scene information</h2></a>
<p>
Let us look at <a href="#example-file-block-header">the file-block header we have seen earlier</a>:<br>
</p>
<ul>
<li>the file-block identifier is <code>'SC'+0x00h</code></li>
<li>the SDNA index is 150</li>
<li>the file-block size is 1404 bytes</li>
</ul>
<p>
Now note that:
<ul>
<li>the structure at index 150 in the DNA is a structure of type 'Scene' (counting from 0).</li>
<li>the associated type ('Scene') in the DNA has the length of 1404 bytes.</li>
</ul>
</p>
<p>
We can map the Scene structure on the data of the file-blocks.
But before we can do that, we have to flatten the Scene-structure.
<code class="block">struct Scene {
ID id; <span class="descr">// 52 bytes long (ID is different a structure)</span>
AnimData *adt; <span class="descr">// 4 bytes long (pointer to an AnimData structure)</span>
Object *camera; <span class="descr">// 4 bytes long (pointer to an Object structure)</span>
World *world; <span class="descr">// 4 bytes long (pointer to an Object structure)</span>
...
float cursor[3]; <span class="descr">// 12 bytes long (array of 3 floats)</span>
...
};
</code>
The first field in the Scene-structure is of type 'ID' with the name 'id'.
Inside the list of DNA structures there is a structure defined for type 'ID' (structure index 17).
<code class="block">struct ID {
void *next, *prev;
struct ID *newid;
struct Library *lib;
char name[24];
short us;
short flag;
int icon_id;
IDProperty *properties;
};
</code>
The first field in this structure has type 'void' and name '*next'. <br>
Looking in the structure list there is no structure defined for type 'void': it is a simple type and therefore the data should be read.
The name '*next' describes a pointer.
As we see, the first 4 bytes of the data can be mapped to 'id.next'.
</p>
<p>
Using this method we'll map a structure to its data. If we want to
read a specific field we know at which offset in the data it is located
and how much space it takes.<br>
The next table shows the output of this flattening process for some
parts of the Scene-structure. Not all rows are described in the table as
there is a lot of information in a Scene-structure.
</p>
<table>
<caption>Flattened SDNA structure 150: Scene</caption>
<thead>
<tr><th>reference</th>
<th>structure</th>
<th>type</th><th>name</th>
<th>offset</th><th>size</th>
<th>description</th></tr>
</thead>
<tbody>
<tr><td>id.next</td><td><a href="#struct:ID">ID</a></td>
<td>void</td><td>*next</td>
<td>0</td>
<td>4</td>
<td>Refers to the next scene</td></tr>
<tr><td>id.prev</td><td><a href="#struct:ID">ID</a></td>
<td>void</td><td>*prev</td>
<td>4</td>
<td>4</td>
<td>Refers to the previous scene</td></tr>
<tr><td>id.newid</td><td><a href="#struct:ID">ID</a></td>
<td>ID</td><td>*newid</td>
<td>8</td>
<td>4</td>
<td></td></tr>
<tr><td>id.lib</td><td><a href="#struct:ID">ID</a></td>
<td>Library</td><td>*lib</td>
<td>12</td>
<td>4</td>
<td></td></tr>
<tr><td>id.name</td><td><a href="#struct:ID">ID</a></td>
<td>char</td><td>name[24]</td>
<td>16</td>
<td>24</td>
<td>'SC'+the name of the scene as displayed in Blender</td></tr>
<tr><td>id.us</td><td><a href="#struct:ID">ID</a></td>
<td>short</td><td>us</td>
<td>40</td>
<td>2</td>
<td></td></tr>
<tr><td>id.flag</td><td><a href="#struct:ID">ID</a></td>
<td>short</td><td>flag</td><td>42</td><td>2</td>
<td></td></tr>
<tr><td>id.icon_id</td><td><a href="#struct:ID">ID</a></td>
<td>int</td><td>icon_id</td><td>44</td>
<td>4</td>
<td></td></tr>
<tr><td>id.properties</td><td><a href="#struct:ID">ID</a></td>
<td>IDProperty</td><td>*properties</td>
<td>48</td>
<td>4</td>
<td></td></tr>
<tr><td>adt</td><td>Scene</td><td>AnimData</td>
<td>*adt</td>
<td>52</td>
<td>4</td>
<td></td></tr>
<tr><td>camera</td><td>Scene</td>
<td>Object</td>
<td>*camera</td>
<td>56</td>
<td>4</td>
<td>Pointer to the current camera</td></tr>
<tr><td>world</td><td>Scene</td>
<td>World</td>
<td>*world</td>
<td>60</td>
<td>4</td>
<td>Pointer to the current world</td></tr>
<tr><td class="skip" colspan="7">Skipped rows</td></tr>
<tr><td>r.xsch</td><td><a href="#struct:RenderData">RenderData</a>
</td><td>short</td><td>xsch</td><td>382</td><td>2</td>
<td>X-resolution of the output when rendered at 100%</td></tr>
<tr><td>r.ysch</td><td><a href="#struct:RenderData">RenderData</a>
</td><td>short</td><td>ysch</td><td>384</td><td>2</td>
<td>Y-resolution of the output when rendered at 100%</td></tr>
<tr><td>r.xparts</td><td><a href="#struct:RenderData">RenderData</a>
</td><td>short</td><td>xparts</td><td>386</td><td>2</td>
<td>Number of x-part used by the renderer</td></tr>
<tr><td>r.yparts</td><td><a href="#struct:RenderData">RenderData</a>
</td><td>short</td><td>yparts</td><td>388</td><td>2</td>
<td>Number of x-part used by the renderer</td></tr>
<tr><td class="skip" colspan="7">Skipped rows</td></tr>
<tr><td>gpd</td><td>Scene</td><td>bGPdata</td><td>*gpd</td><td>1376</td><td>4</td>
<td></td></tr>
<tr><td>physics_settings.gravity</td><td><a href="#struct:PhysicsSettings">PhysicsSettings</a>
</td><td>float</td><td>gravity[3]</td><td>1380</td><td>12</td>
<td></td></tr>
<tr><td>physics_settings.flag</td><td><a href="#struct:PhysicsSettings">PhysicsSettings</a>
</td><td>int</td><td>flag</td><td>1392</td><td>4</td>
<td></td></tr>
<tr><td>physics_settings.quick_cache_step</td><td><a href="#struct:PhysicsSettings">PhysicsSettings</a>
</td><td>int</td><td>quick_cache_step</td><td>1396</td><td>4</td>
<td></td></tr>
<tr><td>physics_settings.rt</td><td><a href="#struct:PhysicsSettings">PhysicsSettings</a>
</td><td>int</td><td>rt</td><td>1400</td><td>4</td>
<td></td></tr>
</tbody>
</table>
<p>
We can now read the X and Y resolution of the Scene:
<ul>
<li>the X-resolution is located on offset 382 of the file-block-data and must be read as a
short.</li>
<li>the Y-resolution is located on offset 384 and is also a short</li>
</ul>
</p>
<div class="box">
<p class="box-title">
Note
</p>
<p>
An array of chars can mean 2 things. The field contains readable
text or it contains an array of flags (not humanly readable).
</p>
</div>
<div class="box">
<p class="box-title">
Note
</p>
<p>
A file-block containing a list refers to the DNA structure and has a count larger
than 1. For example Vertexes and Faces are stored in this way.
</p>
</div>
</body>
</html>

156
doc/build_systems/cmake.txt Normal file
View File

@@ -0,0 +1,156 @@
$Id$
Blender CMake build system
============================
Contents
---------------
1. Introduction
2. Obtaining CMake
3. Obtaining Dependencies
4. Deciding on a Build Environment
5. Configuring the build for the first time
6. Configuring the build after CVS updates
7. Specify alternate Python library versions and locations
1. Introduction
---------------
This document describes general usage of the new CMake scripts. The
inner workings will be described in blender-cmake-dev.txt (TODO).
2. Obtaining CMake
------------------
CMake for can either be downloaded using your favorite package manager
or is also available from the CMake website at http://www.cmake.org
The website also contains some documentation on CMake usage but I found
the man page alone pretty helpful.
3. Obtaining Dependencies
-------------------------
Check from the page
http://www.blender.org/cms/Getting_Dependencies.135.0.html that you
have all dependencies needed for building Blender. Note that for
windows many of these dependencies already come in the lib/windows
module from CVS.
4. Deciding on a Build Environment
----------------------------------
To build Blender with the CMake scripts you first need to decide which
build environment you feel comfortable with. This decision will also be
influenced by the platform you are developing on. The current implementation
have been successfully used to generate build files for the following
environments:
1. Microsoft Visual Studio 2005. There is a free version available
at http://msdn.microsoft.com/vstudio/express/visualc/.
2. Xcode on Mac OSX
3. Unix Makefiles (On Linux and Mac OSX): CMake actually creates make
files which generates nicely color coded output and a percentage
progress indicator.
5. Configuring the build for the first time
-------------------------------------------
CMake allows one to generate the build project files and binary objects
outside the source tree which can be pretty handy in working and experimenting
with different Blender configurations (Audio/NoAudio, GameEngine/NoGameEngine etc.)
while maintaining a clean source tree. It also makes it possible to generate files
for different build systems on the same source tree. This also has benefits for
general CVS management for the developer as patches and submit logs are much cleaner.
Create a directory outside the blender source tree where you would like to build
Blender (from now on called $BLENDERBUILD). On the commandline you can then run
the cmake command to generate your initial build files. First just run 'cmake' which
will inform you what the available generators are. Thn you can run
'cmake -G generator $BLENDERSOURCE' to generate the build files. Here is an example
of all this for Xcode:
% mkdir $BLENDERBUILD
% cd $BLENDERBUILD
% cmake
...
...
--version [file] = Show program name/version banner and exit.
Generators
The following generators are available on this platform:
KDevelop3 = Generates KDevelop 3 project files.
Unix Makefiles = Generates standard UNIX makefiles.
Xcode = Generate XCode project files.
% cmake -G Xcode $BLENDERSOURCE
...
...
-- Configuring blender
-- Configuring blenderplayer
-- Configuring done
-- Generating done
-- Build files have been written to: $BLENDERBUILD
This will generate the build files with default values. Specific features can
be enabled or disabled by running the ccmake "GUI" from $BLENDERBUILD as follows:
% ccmake $BLENDERSOURCE
A number of options appear which can be changed depending on your needs and
available dependencies (e.g. setting WITH_OPENEXR to OFF will disable support
for OpenEXR). It will also allow you to override default and detected paths
(e.g. Python directories) and compile and link flags. When you are satisfied
used ccmake to re-configure the build files and exit.
It is also possible to use the commandline of 'cmake' to override certain
of these settings.
6. Configuring the build after CVS updates
------------------------------------------
The $BLENDERBUILD directory maintains a file called CMakeCache.txt which
remembers the initial run's settings for subsequent generation runs. After
every CVS update it may be a good idea to rerun the generation before building
Blender again. Just rerun the original 'cmake' run to do this, the settings
will be remembered. For the example above the following will do after every
'cvs up':
% cmake -G Xcode $BLENDERSOURCE
7. Specify alternate Python library versions and locations
----------------------------------------------------------
The commandline can be used to override detected/default settings, e.g:
On Unix:
cmake -D PYTHON_LIBRARY=/usr/local/lib/python3.1/config/libpython3.1.so -D PYTHON_INCLUDE_DIRS=/usr/local/include/python3.1 -G "Unix Makefiles" ../blender
On Macs:
cmake -D PYTHON_INCLUDE_DIRS=/System/Library/Frameworks/Python.framework/Versions/3.1/include/python3.1 -G Xcode ../blender
Mote that this should only be needed once per build directory generation because it will keep the overrides in CMakeCache.txt for subsequent runs.
To be continued...
TODO's
------
1. Get CMake to create proper distribution directories for the various platforms
like scons does.
2. Investigate the viability of using CPack to package installs automatically.
3. Refine this document and write detailed developer's document.
4. Make sure all options (ffmpeg, openexr, quicktime) has proper CMake support
on the various platforms.
/Jacques Beaurain (jbinto)

View File

@@ -0,0 +1,194 @@
$Id$
Internals of Blenders SCons scripts
===================================
Scope
------
This document describes the architecture of the SCons scripts for
Blender. An overview of available functionality and how to modify,
extend and maintain the system.
Audience
--------
This document is for developers who need to modify the system,
ie. add or remove new libraries, add new arguments for SCons, etc.
Files and their meaning
-----------------------
The main entry point for the build system is the SConstruct-file in
$BLENDERHOME. This file creates the first BlenderEnvironment to work
with, reads in options, and sets up some directory structures. Further
it defines some targets.
Platform-specific configurations are in $BLENDERHOME/config. The
filenames have the form (platform)-config.py, where platform one of:
* darwin
* linux
* win32-mingw
* win32-vc
The user can override options by creating a file
$BLENDERHOME/user-config.py. It can have any option from
(platform)-config.py. Options in this file will override the platform
defaults.
Much of the actual functionality can be found in the python scripts
in the directory $BLENDERHOME/tools, with Blender.py defining the
bulk of the functionality. btools.py has some helper functions, and
bcolors.py is for the terminal colours. mstoolkit.py and crossmingw.py
are modules which set up SCons for the MS VC++ 2003 toolkit and
the cross-compile toolset for compiling Windows binaries on Linux
respectively. Note: the cross-compile doesn't work yet for Blender,
but is added in preparation for having it work in the distant future.
BlenderEnvironment
------------------
The module Blender.py implements a BlenderEnvironment class, derived
from the SConsEnvironment of SCons. This is done to wrap some often
used functionality. The BlenderEnvironment offers two important
wrappers: BlenderProg() and BlenderLib(). The first one is used to
specify a binary to be built, the second one is used to specify what
static library is built from given sources.
Build a static library called "somelib". The system handles library
pre- and suffixes automatically, you don't need to bother yourself
with these details:
env = BlenderEnvironment(ENV = os.environ) # create an environment
env.BlenderLib(libname="somelib", sources=['list.c','with.c','sources.c'],
includes=['/list/with/include/paths', '.', '..'],
defines=['LIST_WITH', 'CPP_DEFINES', 'TO_USE'],
libtype=['blender', 'common'] # this is a list with libtypes. Normally you don't
# need to specify this, but if you encounter linking
# problems you may need this
priority=[10, 20] # Priorities, list as long as libtype, priority per type
compileflags=['/O2'] # List of compile flags needed for this particular library.
# used only in rare cases, like SOLID, qhull and Bullet
)
There should be no need to ever add an extra BlenderProg to the
existing ones in SConstruct, see that file for its use, and Blender.py
for its implementation.
The new system works so that using these wrappers, has all libraries
(and programs) register with a central repository. This means that
adding a new library is as easy as just creating the new SConscript
and making sure that it gets called properly. Linking and such will
then be handled automatically.
If you want that adding new source files for a certain library
is handled automatically, you can use the Glob() function from
the BlenderEnvironment to create lists of needed files. See
$BLENDERHOME/source/blender/src/SConscript for an example. Keep in
mind that this will add any new file that complies to the rule given
to the Glob() function. There are a few (external) libraries with
which this can't be used, because it'd take files that shouldn't be
compiled, and create subsequentially problems during the linking stage
(like SOLID, qhull, Bullet).
Linking order and priorities
----------------------------
As shown above, you can give a library a priority in a certain
group. If you need to make sure that a Blender library is linked
before or after another one, you can give it a priority. To debug
the priorities us BF_PRIORITYLIST=1 on the command-line while running
a build.
% scons BF_PRIORITYLIST=1
This will give a list with values suggested by the system. Make
changes to all SConscripts in question to reflect or change the
values given by this command. ALWAYS check this after adding a new
internal, external library or core library, and make sure there are
sane values. You can use large and negative numbers to test with,
but after you've got a working linking order, do change the system
to reflect BF_PRIORITYLIST values.
Also, if you find that a library needs to be given multiple times to
the linker, you can do that by giving a python list with the names
of the available library types. They are currently:
B.possible_types = ['core', 'common', 'blender', 'intern',
'international', 'game', 'game2',
'player', 'player2', 'system']
More groups can be added, but that should be carefully considered,
as it may lead to large-scale changes. The current amount of libraries
should suffice.
The central repository is utilised in the SConstruct in two
ways. Firstly, it is used to determine the order of all static
libraries to link into the main Blender executable. Secondly, it
is used to keep track of all built binaries and their location,
so that they can be properly copied to BF_INSTALLDIR.
The libraries can be fetched in their priority order with
create_blender_liblist from Blender.py, see the SConstruct on how
it is used.
The program repository is the global list program_list from
Blender.py. See SConstruct for its usage.
Adding a new option and libraries
---------------------------------
Lets say we want to add WITH_BF_NEWLIB, which will
enable or disable a new feature library with sources in
$BLENDERHOME/source/blender/newlib. This 'newlib' needs external
headers from a 3rd party library '3rdparty'. For this we want to
add a set of options BF_3RDPARTY, BF_3RDPARTY_INC, BF_3RDPARTY_LIB,
BF_3RDPARTY_LIBPATH:
1) Add all mentiond options to all (platform)-config.py
files. WITH_BF_NEWLIB is a boolean option ('true', 'false'),
the rest are strings with paths and library names. See the
OpenEXR options for example.
2) Add all options to the argument checking function
validate_arguments() in btools.py. See again OpenEXR options
for example.
3) Add all options to the option reading function read_opts()
in btools.py. See again OpenEXR options for example. All default
values can be empty, as the actual default values are in the
(platform)-config.py files.
4) Add BF_3RDPARTY_LIB to the function setup_syslibs()
and BF_3RDPARTY_LIBPATH to the function setup_staticlibs()
in Blender.py
At this stage we have prepared all option setting and linking needs,
but we still need to add in the compiling of the 'newlib'.
5) Create a SConscript in $BLENDERHOME/source/blender/newlib. Look
at ie. $BLENDERHOME/source/blender/src/SConscript for
template. The new SConscript will register the new library
like so:
env.BlenderLib(libname='newlib', sources=sourcefiles, includes=incs) # the rest of the arguments get defaults = empty lists and values
6) Edit $BLENDERHOME/source/blender/SConscript with the following
addition:
if env['WITH_BF_NEWLIB'] == 1:
SConscript(['newlib/SConscript'])
After this you can see if this works by trying to build:
% scons WITH_BF_NEWLIB=1 # build with newlib
% scons WITH_BF_NEWLIB=0 # disable newlib
This is all what should be needed. Changing the library name doesn't
need changes elsewhere in the system, as it is handled automatically
with the central library repository.
Enjoy the new system!
/Nathan Letwory (jesterKing)

231
doc/build_systems/scons.txt Normal file
View File

@@ -0,0 +1,231 @@
$Id$
Blenders SCons build scripts
============================
Introduction
------------
Since the beginning of 2004 Blender has had the SCons system as a
build option. SCons is a Python-based, accurate build system. The
scripts that were implemented in the first iteration worked, but
the system grew quickly into such a state that maintaining it became
a nightmare, and adding new features was just horrible, leading to
many hacks without much sense in the overall structure.
The rewrite has been waiting for a long time. Jonathan Jacobs provided
a first overhaul of the scripts, which I used in the first phase of
the rewrite. To make the system as maintainable as possible I made
some radical changes, but thanks go to Jonathan for providing me
with the patch to get started.
This document describes the usage of the new SCons scripts. The
inner workings are described in scons-dev.txt.
Building Blender
----------------
To build Blender with the SCons scripts you need a full Python
install, version 2.4 or later (http://www.python.org). We already provide
a scons-local installation, which can be found in the scons/ subdirectory.
This document uses the scons-local installation for its examples.
Check from the page
http://www.blender.org/development/building-blender/getting-dependencies/
that you have all dependencies needed for building Blender. Note that for
windows many of these dependencies already come in the lib/windows module
from CVS.
In the base directory of the sources (from now on called $BLENDERHOME)
you'll see a file named SConstruct. This is the entry point for the
SCons build system. In a terminal, change to this directory. To just
build, start the SCons entry script on Windows (will be used for the remainder
of this document):
% python scons\scons.py
On a Unix-compatible system it would be
% python ./scons/scons.py
This will start the build process with default values. Depending
on your platform you may see colour in your output (non-Windows
machines). In the the beginning an overview of targets and arguments
from the command-line is given, then all libraries and binaries to
build are configured.
The build uses BF_BUILDDIR to build into and BF_INSTALLDIR to
finally copy all needed files to get a proper setup. The BF_DOCDIR is
used to generate Blender Python documentation files to. These
variables have default values for every platform in
$BLENDERHOME/config/(platform)-config.py. After the build successfully
completes, you can find everything you need in BF_INSTALLDIR.
If you want to create the installer package of Blender on Windows you'll
need to install nullsoft scriptable install system from http://nsis.sf.net.
As an extra dependency, you need the MoreInfo plugin too. The creation of
the installer is tied into the build process and can be triggered with:
% python scons\scons.py nsis
Configuring the build
---------------------
The default values for your platform can be found in the directory
$BLENDERHOME/config. Your platform specific defaults are in
(platform)-config.py, where platform is one of:
- linux, for machines running Linux
- win32-vc, for Windows machines, compiling with a Microsoft compiler
- win32-mingw, for Windows machines, compiling with the MingW compiler
- darwin, for OS X machines
(TBD: add cygwin, solaris and freebsd support)
These files you will normally not change. If you need to override
a default value, make a file called $BLENDERHOME/user-config.py, and copy
settings from the config/(platform)-config.py that you want to change. Don't
copy the entire file (unless explicitely stated in the configuration file),
because you may not get updated options you don't change yourself, which may
result in build errors.
You can use BF_CONFIG argument to override the default user-config.py
check. This is just like the user-config.py, but just with another name:
% python scons\scons.py BF_CONFIG=myownsettings
If you want to quickly test a new setting, you can give the option
also on the command-line:
% python scons\scons.py BF_BUILDDIR=../mybuilddir WITH_BF_OPENEXR=0
This command sets the build directory to BF_BUILDDIR and disables
OpenEXR support.
If you need to know what can be set through the command-line, run
scons with -h:
% python scons\scons.py -h
This command will print a long list with settable options and what
every option means. Many of the default values will be empty, and
from a fresh checkout without a user-config.py the actual values
are the defaults as per $BLENDERHOME/config/(platform)-config.py
(unless you have overridden any of them in your
$BLENDERHOME/user-config.py).
NOTE: The best way to avoid confusion is the
copy $BLENDERHOME/config/(platform)-config.py to
$BLENDERHOME/user-config.py. You should NEVER have to modify
$BLENDERHOME/config/(platform)-config.py
Configuring the output
----------------------
This rewrite features a cleaner output during the build process. If
you need to see the full command-line for compiles, then you can
change that behaviour. Also the use of colours can be changed:
% python scons\scons.py BF_FANCY=0
This will disable the use of colours.
% python scons\scons.py BF_QUIET=0
This will give the old, noisy output. Every command-line per
compile is printed out in its full glory. This is very useful when
debugging problems with compiling, because you can see what the
included paths are, what defines are given on the command-line,
what compiler switches are used, etc.
Compiling Only Some Libraries
-----------------------------
Our implementation now has support for specifying a list of libraries that are
exclusively compiled, ignoring all other libraries. This is invoked
with the BF_QUICK arguments; for example:
% python scons\scons.py BF_QUICK=src,bf_blenkernel
Note that this not the same as passing a list of folders as in the
makefile's "quicky" command. In Scons, all of Blender's code modules
are in their own static library; this corresponds to one-lib-per-folder
in some cases (especially in blender/source/blender).
To obtain a list of the libraries, simple fire up scons and CTRL-C out once
it finishes configuring (and printing to the console) the library list.
Compiling Libraries With Debug Profiling
----------------------------------------
Scons has support for specifying a list of libraries that are compiled
with debug profiling enabled. This is implemented in two commands:
BF_QUICKDEBUG which is a command-line argument and BF_DEBUG_LIBS, which goes
in your user-config.py
BF_QUICKDEBUG is similar to BF_QUICK:
% python scons\scons.py BF_QUICKDEBUG=src,bf_blenkernel,some-other-lib
To use BF_DEBUG_LIBS, put something like the following in you user-config.py:
BF_DEBUG_LIBS = ['bf_blenlib', 'src', 'some_lib']
For instructions on how to find the names of the libraries (folders) you
wish to use, see the above section. Note that the command BF_DEBUG
(see below) will override these settings and compile ALL of Blender with
debug symbols. Also note that BF_QUICKDEBUG and BF_DEBUG_LIBS are combined;
for example, setting BF_QUICKDEBUG won't overwrite the contents of BF_DEBUG_LIBS.
Supported toolset
-----------------
WINDOWS
* msvc, this is a full install of Microsoft Visual C++. You'll
likely have the .NET Framework SDK, Platform SDK and DX9 SDK
installed * mstoolkit, this is the free MS VC++ 2003 Toolkit. You
need to verify you have also the SDKs installed as mentioned
for msvc. * mingw, this is a minimal MingW install. TBD: write
proper instructions on getting needed packages.
On Windows with all of the three toolset installed you need to
specify what toolset to use
% python scons\scons.py BF_TOOLSET=msvc
% python scons\scons.py BF_TOOLSET=mingw
LINUX and OS X
Currently only the default toolsets are supported for these platforms,
so nothing special needs to be told to SCons when building. The
defaults should work fine in most cases.
Examples
--------
Build Blender with the defaults:
% python scons\scons.py
Build Blender, but disable OpenEXR support:
% python scons\scons.py WITH_BF_OPENEXR=0
Build Blender, enable debug symbols:
% python scons\scons.py BF_DEBUG=1
Build Blender, install to different directory:
% python scons\scons.py BF_INSTALLDIR=../myown/installdir
Build Blender in ../myown/builddir and install to ../myown/installdir:
% python scons\scons.py BF_BUILDDIR=../myown/builddir BF_INSTALLDIR=../myown/installdir
Clean BF_BUILDDIR:
% python scons\scons.py clean
/Nathan Letwory (jesterKing)

View File

@@ -31,7 +31,7 @@ PROJECT_NAME = Blender
# This could be handy for archiving the generated documentation or
# if some version control system is used.
PROJECT_NUMBER = "V2.57"
PROJECT_NUMBER = "V2.59"
# 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

View File

@@ -0,0 +1,201 @@
{%- block doctype -%}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
{%- endblock %}
{%- set script_files = script_files + [pathto("_static/jquery.sidebar.js", 1)] %}
{%- set reldelim1 = reldelim1 is not defined and ' &raquo;' or reldelim1 %}
{%- set reldelim2 = reldelim2 is not defined and ' •' or reldelim2 %}
{%- macro relbar() %}
<div class="subnav boxheader">
<ul class="noprint"><li><a href="http://wiki.blender.org/index.php/Dev:Contents">Documentation</a></li><li></li><li><a href="http://www.blender.org/development/report-a-bug/">Report a Bug</a></li><li></li><li><a href="http://wiki.blender.org/index.php/Dev:Doc/Process/Patches">Submit a Patch</a></li><li></li><li><a href="http://www.blender.org/development/release-logs/">Release Logs</a></li><li></li><li><a href="http://www.blender.org/development/building-blender/">Building Blender</a></li><li></li><li><a href="http://wiki.blender.org/index.php/Dev:Doc/Projects">Current Projects</a></li><li></li><li><a href="http://wiki.blender.org/index.php/Dev:Source/Architecture">Architecture</a></li><li></li><li><a href="http://www.blender.org/documentation/250PythonDoc/contents.html">Python API</a></li><li></li><li><a href="http://wiki.blender.org">Wiki</a></li></ul>
</div>
<div class="related subnav">
<h3>{{ _('Navigation') }}</h3>
<ul>
{%- for rellink in rellinks %}
<li class="right">
<a href="{{ pathto(rellink[0]) }}" title="{{ rellink[1]|striptags }}"
{{ accesskey(rellink[2]) }}>{{ rellink[3] }}</a>
{%- if not loop.first %}{{ reldelim2 }}{% endif %}</li>
{%- endfor %}
{%- block rootrellink %}
<li><a href="{{ pathto(master_doc) }}">{{ shorttitle|e }}</a>{{ reldelim1 }}</li>
{%- endblock %}
{%- for parent in parents %}
<li><a href="{{ parent.link|e }}" {% if loop.last %}{{ accesskey("U") }}{% endif %}>{{ parent.title }}</a>{{ reldelim1 }}</li>
{%- endfor %}
{%- block relbaritems %} {% endblock %}
</ul>
</div>
{%- endmacro %}
{%- macro sidebar() %}
{%- if not embedded %}{% if not theme_nosidebar|tobool %}
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
{%- block sidebarlogo %}
{%- if logo %}
<p class="logo"><a href="{{ pathto(master_doc) }}">
<img class="logo" src="{{ pathto('_static/' + logo, 1) }}" alt="Logo"/>
</a></p>
{%- endif %}
{%- endblock %}
{%- block sidebartoc %}
{%- if display_toc %}
<h3><a href="{{ pathto(master_doc) }}">{{ _('Table Of Contents') }}</a></h3>
{{ toc }}
{%- endif %}
{%- endblock %}
{%- block sidebarrel %}
{%- if prev %}
<h4>{{ _('Previous topic') }}</h4>
<p class="topless"><a href="{{ prev.link|e }}"
title="{{ _('previous chapter') }}">{{ prev.title }}</a></p>
{%- endif %}
{%- if next %}
<h4>{{ _('Next topic') }}</h4>
<p class="topless"><a href="{{ next.link|e }}"
title="{{ _('next chapter') }}">{{ next.title }}</a></p>
{%- endif %}
{%- endblock %}
{%- block sidebarsourcelink %}
{%- if show_source and has_source and sourcename %}
<h3>{{ _('This Page') }}</h3>
<ul class="this-page-menu">
<li><a href="{{ pathto('_sources/' + sourcename, true)|e }}"
rel="nofollow">{{ _('Show Source') }}</a></li>
</ul>
{%- endif %}
{%- endblock %}
{%- if customsidebar %}
{% include customsidebar %}
{%- endif %}
{%- block sidebarsearch %}
{%- if pagename != "search" %}
<div id="searchbox" style="display: none">
<h3>{{ _('Quick search') }}</h3>
<form class="search" action="{{ pathto('search') }}" method="get">
<input type="text" name="q" size="18" />
<input type="submit" value="{{ _('Go') }}" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
<p class="searchtip">
{{ _('Enter search terms or a module, class or function name.') }}
</p>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
{%- endif %}
{%- endblock %}
</div>
</div>
{%- endif %}{% endif %}
{%- endmacro %}
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
{{ metatags }}
{%- if not embedded and docstitle %}
{%- set titlesuffix = " &mdash; "|safe + docstitle|e %}
{%- else %}
{%- set titlesuffix = "" %}
{%- endif %}
<title>{{ title|striptags }}{{ titlesuffix }}</title>
<link rel="stylesheet" href="{{ pathto('_static/' + style, 1) }}" type="text/css" />
<link rel="stylesheet" href="{{ pathto('_static/pygments.css', 1) }}" type="text/css" />
{%- if not embedded %}
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '{{ pathto("", 1) }}',
VERSION: '{{ release|e }}',
COLLAPSE_MODINDEX: false,
FILE_SUFFIX: '{{ file_suffix }}',
HAS_SOURCE: {{ has_source|lower }}
};
</script>
{%- for scriptfile in script_files %}
<script type="text/javascript" src="{{ pathto(scriptfile, 1) }}"></script>
{%- endfor %}
{%- if use_opensearch %}
<link rel="search" type="application/opensearchdescription+xml"
title="{% trans docstitle=docstitle|e %}Search within {{ docstitle }}{% endtrans %}"
href="{{ pathto('_static/opensearch.xml', 1) }}"/>
{%- endif %}
{%- if favicon %}
<link rel="shortcut icon" href="{{ pathto('_static/' + favicon, 1) }}"/>
{%- endif %}
{%- endif %}
{%- block linktags %}
{%- if hasdoc('about') %}
<link rel="author" title="{{ _('About these documents') }}" href="{{ pathto('about') }}" />
{%- endif %}
{%- if hasdoc('genindex') %}
<link rel="index" title="{{ _('Index') }}" href="{{ pathto('genindex') }}" />
{%- endif %}
{%- if hasdoc('search') %}
<link rel="search" title="{{ _('Search') }}" href="{{ pathto('search') }}" />
{%- endif %}
{%- if hasdoc('copyright') %}
<link rel="copyright" title="{{ _('Copyright') }}" href="{{ pathto('copyright') }}" />
{%- endif %}
<link rel="top" title="{{ docstitle|e }}" href="{{ pathto('index') }}" />
{%- if parents %}
<link rel="up" title="{{ parents[-1].title|striptags }}" href="{{ parents[-1].link|e }}" />
{%- endif %}
{%- if next %}
<link rel="next" title="{{ next.title|striptags }}" href="{{ next.link|e }}" />
{%- endif %}
{%- if prev %}
<link rel="prev" title="{{ prev.title|striptags }}" href="{{ prev.link|e }}" />
{%- endif %}
{%- endblock %}
{%- block extrahead %} {% endblock %}
</head>
<body>
{%- block header %}
<div class="noprint" id="navcontainer"><a href="http://www.blender.org/"><img width="140" height="50" title="blender.org home page" alt="blender.org home page" src="http://www.blender.org/fileadmin/site/_gfx/nav-home.png"></a><a href="http://www.blender.org/features-gallery/"><img width="140" height="50" title="Features &amp; Gallery" alt="Features &amp; Gallery" src="http://www.blender.org/fileadmin/site/_gfx/nav-features.png"></a><a href="http://www.blender.org/download/get-blender/"><img width="140" height="50" title="Download" alt="Download" src="http://www.blender.org/fileadmin/site/_gfx/nav-download.png"></a><a href="http://www.blender.org/education-help/"><img width="140" height="50" title="Tutorials &amp; Help" alt="Tutorials &amp; Help" src="http://www.blender.org/fileadmin/site/_gfx/nav-help.png"></a><a href="http://www.blender.org/community/user-community/"><img width="140" height="50" title="Community" alt="Community" src="http://www.blender.org/fileadmin/site/_gfx/nav-community.png"></a><a href="http://www.blender.org/development/"><img width="140" height="50" title="Development" alt="Development" src="http://www.blender.org/fileadmin/site/_gfx/nav-development-on.png"></a><a href="http://www.blender.org/e-shop/"><img width="140" height="50" title="e-Shop" alt="e-Shop" src="http://www.blender.org/fileadmin/site/_gfx/nav-eshop.png"></a></div>
{% endblock %}
<div class="document">
<div id="pageheader"></div>
{%- block relbar1 %}{{ relbar() }}{% endblock %}
{%- block sidebar1 %} {# possible location for sidebar #} {% endblock %}
{%- block document %}
<div class="documentwrapper">
{%- if not embedded %}{% if not theme_nosidebar|tobool %}
<div class="bodywrapper">
{%- endif %}{% endif %}
<div class="body">
{% block body %} {% endblock %}
</div>
{%- if not embedded %}{% if not theme_nosidebar|tobool %}
</div>
{%- endif %}{% endif %}
</div>
{%- endblock %}
{%- block sidebar2 %}{{ sidebar() }}{% endblock %}
<div class="clearer"></div>
{%- block footer %}
<div class="footer">
{%- if hasdoc('copyright') %}
{% trans path=pathto('copyright'), copyright=copyright|e %}&copy; <a href="{{ path }}">Copyright</a> {{ copyright }}.{% endtrans %}
{%- else %}
{% trans copyright=copyright|e %}&copy; Copyright {{ copyright }}.{% endtrans %}
{%- endif %}
{%- if last_updated %}
{% trans last_updated=last_updated|e %}Last updated on {{ last_updated }}.{% endtrans %}
{%- endif %}
{%- if show_sphinx %}
{% trans sphinx_version=sphinx_version|e %}Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> {{ sphinx_version }}.{% endtrans %}
{%- endif %}
</div><b class="round"><b id="r1"></b><b id="r2"></b><b id="r3"></b><b id="r4"></b></b>
{%- endblock %}
</div>
</body>
</html>

View File

@@ -0,0 +1,4 @@
{% extends "layout.html" %}
{% block body %}
{{ body }}
{% endblock %}

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

View File

@@ -0,0 +1,654 @@
/**
* Sphinx stylesheet -- default theme
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
@import url("basic.css");
/* -- page layout ----------------------------------------------------------- */
#navcontainer {
height: 50px;
margin: 0 auto;
position: relative;
width: 980px;
}
#navcontainer img {
width: 140px;
height: 50px;
}
#pageheader {
background-image:url("bg.png");
height:80px;
position:relative;
}
body {
font-family: {{ theme_bodyfont }};
font-size: 12px;
line-height: 145%;
background-color: {{ theme_footerbgcolor }};
color: {{ theme_textcolor }};
min-width: 980px;
margin: 0;
padding: 0;
}
div.document {
margin:20px auto 0;
position:relative;
text-align:left;
width:980px;
/* background-color: {{ theme_sidebarbgcolor }};*/
}
div.documentwrapper {
float: left;
width: 100%;
background-color: {{ theme_bgcolor }};
border-color: {{ theme_bordercolor }};
border-style:solid;
border-width:0 1px;
margin:0 auto;
min-height:30em;
padding:35px;
/* position:relative;*/
text-align:left;
width:908px;
}
div.bodywrapper {
margin: 0 0 0 230px;
}
div.body {
background-color: {{ theme_bgcolor }};
color: {{ theme_textcolor }};
padding: 0;
width: 640px;
}
{%- if theme_rightsidebar|tobool %}
div.bodywrapper {
margin: 0 230px 0 0;
}
{%- endif %}
div.footer {
background: #292929;
border-left: 1px solid #363636;
border-right: 1px solid #363636;
color: #ffffff;
/* width: 100%;*/
margin: 0 auto;
padding: 20px 20px 15px 35px;
text-align: center;
font-size: 75%;
}
div.footer+.round b {
display: block;
background: #292929;
width: auto;
}
div.footer+.round #r1 {
border-left: 1px solid #363636;
border-right: 1px solid #363636;
height: 2px;
margin: 0 1px;
}
div.footer+.round #r2 {
border-left: 1px solid #363636;
border-right: 1px solid #363636;
height: 1px;
margin: 0 2px;
}
div.footer+.round #r3 {
border-left: 1px solid #363636;
border-right: 1px solid #363636;
height: 1px;
margin: 0 3px;
}
div.footer+.round #r4 {
border-bottom: 1px solid #363636;
height: 0px;
margin: 0 5px;
}
div.footer a {
color: {{ theme_footertextcolor }};
text-decoration: underline;
}
.boxheader {
background-color:#3E4D5E;
}
.subnav {
height:auto !important;
min-height:15px;
padding:9px 0px 9px 37px;
position:relative;
}
div.related {
width:auto;
font-size:100%;
font-weight:400;
background-color: {{ theme_relbarbgcolor }};
line-height: 145%;
color: {{ theme_relbartextcolor }};
}
div.related li {
font-size:0.9em;
}
div.related li.right {
margin: 0;
word-spacing: 3px;
}
div.subnav li {
display:inline;
list-style-type:none;
margin:0;
padding:0 7px 0 0;
}
div.subnav ul {
display:inline;
margin:0;
padding:0;
}
.subnav a {
font-weight: bold;
color: #fff;
}
.subnav li.subnav-active a {
color:#F39410;
}
div.related a {
color: {{ theme_relbarlinkcolor }};
}
div.related a:active {
color: {{ theme_relbaractlinkcolor }};
}
div.sphinxsidebar {
width: 280px;
font-size: 100%;
{%- if theme_stickysidebar|tobool %}
/* top: 30px;*/
margin: 0;
position: absolute;
overflow: auto;
height: 100%;
{%- endif %}
{%- if theme_rightsidebar|tobool %}
float: right;
{%- if theme_stickysidebar|tobool %}
right: 0;
{%- endif %}
{%- endif %}
}
div.sphinxsidebarwrapper {
width: inherit;
padding: 0;
position: absolute;
margin-top: 35px;
font-size: 8pt;
}
div.sphinxsidebarwrapper.fixed {
position:fixed;
top:10px;
margin-top: 0;
}
{%- if theme_stickysidebar|tobool %}
/* this is nice, but it leads to hidden headings when jumping
to an anchor */
/*
div.related {
position: fixed;
}
div.documentwrapper {
margin-top: 30px;
}
*/
{%- endif %}
div.sphinxsidebar h3 {
font-family: {{ theme_headfont }};
color: {{ theme_sidebartextcolor }};
font-size: 12px;
font-weight: bold;
background: #3E4D5E url("rnd.png") no-repeat top left;
height: 16px;
margin: 0;
padding: 10px 5px 10px 18px;
}
div.sphinxsidebar h3 a {
color: {{ theme_sidebartextcolor }};
}
div.sphinxsidebar h4 {
font-family: {{ theme_headfont }};
color: {{ theme_sidebartextcolor }};
background: #3E4D5E url("rnd.png") no-repeat top left;
height: 16px;
font-size: 12px;
font-weight: bold;
margin: 0;
padding: 10px 5px 10px 18px;
}
div.sphinxsidebar form {
margin: 0;
padding: 10px;
background-color: #292929;
{%- if theme_rightsidebar|tobool %}
border-right: 1px solid {{ theme_bordercolor }};
{%- endif %}
}
div.sphinxsidebar p {
background-color: #292929;
padding: 5px 10px 10px 10px;
color: {{ theme_sidebartextcolor }};
{%- if theme_rightsidebar|tobool %}
border-right: 1px solid {{ theme_bordercolor }};
{%- endif %}
margin-top: 0;
}
div.sphinxsidebar p.topless {
margin-bottom: 25px;
}
div.sphinxsidebar ul {
background-color: #292929;
margin: 0;
padding: 0;
color: {{ theme_sidebartextcolor }};
}
div.sphinxsidebar > div > ul {
margin-bottom: 25px;
padding:10px;
}
div.sphinxsidebar a {
color: {{ theme_sidebarlinkcolor }};
}
div.sphinxsidebar input {
border: 1px solid {{ theme_sidebarlinkcolor }};
font-family: sans-serif;
font-size: 1em;
}
/* -- body styles ----------------------------------------------------------- */
a {
color: {{ theme_linkcolor }};
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
/*div.body h1,*/
div.body h2,
div.body h3,
div.body h4,
div.body h5,
div.body h6 {
font-family: {{ theme_headfont }};
background-color: {{ theme_headbgcolor }};
font-weight: bold;
color: {{ theme_headtextcolor }};
/* border-bottom: 1px solid #ccc;*/
margin: 20px -20px 10px -20px;
padding: 3px 0 3px 10px;
}
div.body h1 { margin-top: 0; font-size: 200%;
color:#FFFAE0;
font-family:"Helvetica","Arial",sans-serif;
font-size:34px;
font-weight:normal;
left:32px;
line-height:26px;
margin-top:0;
position:absolute;
top:36px;
}
div.body h2 { font-size: 160%; }
div.body h3 { font-size: 140%; }
div.body h4 { font-size: 120%; }
div.body h5 { font-size: 110%; }
div.body h6 { font-size: 100%; }
a.headerlink {
color: {{ theme_headlinkcolor }};
font-size: 0.8em;
padding: 0 4px 0 4px;
text-decoration: none;
}
h1:hover > a.headerlink {
display:none;
}
a.headerlink:hover {
background-color: {{ theme_headlinkcolor }};
color: white;
}
div.body p, div.body dd, div.body li {
text-align: justify;
line-height: 130%;
}
div.note, div.seealso, div.topic, div.warning {
color:white;
}
div.admonition p.admonition-title + p {
display: inline;
}
div.note {
background-color: #555;
border: 1px solid #ddd;
}
div.seealso {
background-color: #525241;
border: 1px solid #ff6;
}
div.topic {
background-color: #eee;
}
div.warning {
background-color: #B64444;
border: 1px solid #990606;
}
p.admonition-title {
display: inline;
}
p.admonition-title:after {
content: ":";
}
dl div.admonition {
border:medium none;
margin:0;
padding:2px 5px 2px 0;
}
dl.class > dd > div.warning p.admonition-title,
dl.class > dd > div.note p.admonition-title {
display:none;
}
dl.class > dd > div.admonition.warning p,
dl.class > dd > div.admonition.note p {
margin:0;
}
dl.class > dd > div.admonition.warning,
dl.class > dd > div.admonition.note {
margin-bottom:12px;
}
dl div.admonition.note p.admonition-title, dl div.admonition.warning p.admonition-title {
color:inherit;
}
dl div.admonition.warning p {
font-weight:bold;
line-height:150%;
}
dl div.admonition.warning p * {
font-weight:normal;
}
dl div.admonition p.admonition-title {
color:#555555;
display:block;
float:left;
margin:0;
padding-right:12px;
text-align:right;
width:90px;
}
dl div.admonition p.admonition-title+p, dl div.admonition p {
display:block;
margin:0 0 0 102px;
}
dl div.note {
background:none;
color:#E8E481;
}
dl div.warning {
background:none;
color:#FC3030;
}
dl div.seealso {
background:none;
}
dl div.admonition.seealso p+p {
color:#222;
}
dl div.seealso a {
margin-left:-1.3ex;
}
div.admonition.warning pre {
background: #0F0704;
color: #fc3030;
}
div.admonition pre {
margin: 6px 0;
overflow: visible;
white-space: pre-wrap;
}
pre {
padding: 10px;
background-color: #000;
color: #fff;
line-height: normal;
border: 0 solid white;
}
dl.function>dt, dl.method>dt {
text-indent:-118px;
padding-left: 118px;
}
dl.function>dt em, dl.method>dt em {
color: #97b9cf;
}
dl.function>dd em, dl.method>dd em {
color: #97b9cf;
font-weight:bold;
}
dl.function table.field-list tr:first-child td.field-body, dl.method table.field-list tr:first-child td.field-body {
color: #728c96;
}
dl.function>dt em:before, dl.method>dt em:before {
content: " ";
display: block;
}
dl.function>dd>p,dl.method>dd>p,dl.attribute>dd>p,
dl[class]>dd>ol,dl[class]>dd>ul {
color: #999;
}
dl.data>dt {
color:#08C659;
}
dl.data>dd>p {
color:#069643;
}
dl.class>dt {
color: #82a3c7;
}
dl.class>dd>p,dl.class>dd>ol,dl.class>dd>ul {
color: #637b96;
}
dl.function>dt,dl.method>dt,dl.attribute>dt {
color: #fcb100;
}
dl.function>dd>p,dl.method>dd>p,dl.attribute>dd>p,
dl.function>dd>p+ol,dl.method>dd>p+ol,dl.attribute>dd>p+ol,
dl.function>dd>p+ul,dl.method>dd>p+ul,dl.attribute>dd>p+ul {
color: #cb8f00;
}
dl.function>dd>p, dl.method>dd>p, dl.attribute>dd>p {
margin: 0 0 3px 102px;
}
dl.function>dd>p:first-child:before, dl.method>dd>p:first-child:before, dl.attribute>dd>p:first-child:before {
content:"Description:";
color:#555;
font-weight:bold;
font-style:normal;
width:90px;
display:inline-block;
margin-left:-102px;
text-align:right;
padding-right:12px;
}
dt:target, .highlight {
color: #444;
background: #333;
}
.highlight {
background: #E2C788;
}
h1 .highlight {
color:inherit;
background:inherit;
}
dl {
margin-bottom: 25px;
}
dd {
margin: 3px 0 10px 15px;
}
.field-body tt.literal {
font-weight: normal;
}
tt {
background-color: #444;
padding: 0 1px 0 1px;
font-size: 0.95em;
}
.warning tt {
background: #cc6262;
}
.note tt {
background: #444;
}
dl .warning tt {
background:#0F0704;
display:block;
}
dl .note tt {
background:#2C2A1B;
}
table.indextable tr.cap {
background-color: transparent;
}
col.field-name {
width:90px;
}
dd table {
margin-bottom: 0;
}
table.field-list th {
color:#555;
padding:0;
text-align:right;
}
table.field-list td.field-body {
color:#999999;
padding-left:12px;
}
table.field-list td.field-body ul.first {
padding-left:0;
list-style:none;
margin-left:0;
}
dl.function>dd>ol, dl.method>dd>ol, dl.attribute>dd>ol,
dl.function>dd>ul, dl.method>dd>ul, dl.attribute>dd>ul,
dl.function>dd>div[class|="highlight"], dl.method>dd>div[class|="highlight"],
dl.attribute>dd>div[class|="highlight"] {
margin-left:102px;
}
dl.function>dd>ol, dl.method>dd>ol, dl.attribute>dd>ol,
dl.function>dd>ul, dl.method>dd>ul, dl.attribute>dd>ul,
dl.class>dd>ol, dl.class>dd>ul {
padding-left:20px;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,26 @@
$(document).ready(function () {
var top = $('.sphinxsidebarwrapper').offset().top - parseFloat($('.sphinxsidebarwrapper').css ('marginTop').replace(/auto/, 0));
var colheight = parseFloat($('.sphinxsidebarwrapper').css('height').replace(/auto/, 0));
$(window).scroll(function (event) {
// what the y position of the scroll is
var y = $(this).scrollTop();
// whether that's below the form
if (y >= top) {
//colheight is checked and according to its vaule the scrolling
//is triggered or not
if (colheight <= window.innerHeight) {
// if so, ad the fixed class
$('.sphinxsidebarwrapper').addClass('fixed');
} else {
// otherwise remove it
$('.sphinxsidebarwrapper').removeClass('fixed');
}
} else {
// otherwise remove it
$('.sphinxsidebarwrapper').removeClass('fixed');
}
});
});

View File

@@ -0,0 +1,61 @@
.hll { background-color: #ffffcc }
.c { color: #7f7f7f; font-style: italic } /* Comment */
.err { border: 1px solid #FF0000 } /* Error */
.k { color: #0088ff; font-weight: bold } /* Keyword */
.o { color: #993399 } /* Operator */
.cm { color: #7f7f7f; font-style: italic } /* Comment.Multiline */
.cp { color: #007020 } /* Comment.Preproc */
.c1 { color: #408090; font-style: italic } /* Comment.Single */
.cs { color: #408090; background-color: #fff0f0 } /* Comment.Special */
.gd { color: #A00000 } /* Generic.Deleted */
.ge { font-style: italic } /* Generic.Emph */
.gr { color: #FF0000 } /* Generic.Error */
.gh { color: #000080; font-weight: bold } /* Generic.Heading */
.gi { color: #00A000 } /* Generic.Inserted */
.go { color: #303030 } /* Generic.Output */
.gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */
.gs { font-weight: bold } /* Generic.Strong */
.gu { color: #800080; font-weight: bold } /* Generic.Subheading */
.gt { color: #0040D0 } /* Generic.Traceback */
.kc { color: #007020; font-weight: bold } /* Keyword.Constant */
.kd { color: #007020; font-weight: bold } /* Keyword.Declaration */
.kn { color: #FFFF32; font-weight: bold } /* Keyword.Namespace */
.kp { color: #007020 } /* Keyword.Pseudo */
.kr { color: #FFFF32; font-weight: bold } /* Keyword.Reserved */
.kt { color: #902000 } /* Keyword.Type */
.m { color: #00BAFF } /* Literal.Number */
.s { color: #B7C274 } /* Literal.String */
.na { color: #4070a0 } /* Name.Attribute */
.nb { color: #007020 } /* Name.Builtin */
.nc { color: #0e84b5; font-weight: bold } /* Name.Class */
.no { color: #60add5 } /* Name.Constant */
.nd { color: #555555; font-weight: bold } /* Name.Decorator */
.ni { color: #d55537; font-weight: bold } /* Name.Entity */
.ne { color: #007020 } /* Name.Exception */
.nf { color: #06287e } /* Name.Function */
.nl { color: #002070; font-weight: bold } /* Name.Label */
.nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */
.nt { color: #062873; font-weight: bold } /* Name.Tag */
.nv { color: #bb60d5 } /* Name.Variable */
.ow { color: #007020; font-weight: bold } /* Operator.Word */
.w { color: #bbbbbb } /* Text.Whitespace */
.mf { color: #00BAFF } /* Literal.Number.Float */
.mh { color: #00BAFF } /* Literal.Number.Hex */
.mi { color: #00BAFF } /* Literal.Number.Integer */
.mo { color: #00BAFF } /* Literal.Number.Oct */
.sb { color: #B7C274 } /* Literal.String.Backtick */
.sc { color: #B7C274 } /* Literal.String.Char */
.sd { color: #B7C274; font-style: italic } /* Literal.String.Doc */
.s2 { color: #B7C274 } /* Literal.String.Double */
.se { color: #B7C274; font-weight: bold } /* Literal.String.Escape */
.sh { color: #B7C274 } /* Literal.String.Heredoc */
.si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */
.sx { color: #c65d09 } /* Literal.String.Other */
.sr { color: #235388 } /* Literal.String.Regex */
.s1 { color: #4070a0 } /* Literal.String.Single */
.ss { color: #517918 } /* Literal.String.Symbol */
.bp { color: #007020 } /* Name.Builtin.Pseudo */
.vc { color: #bb60d5 } /* Name.Variable.Class */
.vg { color: #bb60d5 } /* Name.Variable.Global */
.vi { color: #bb60d5 } /* Name.Variable.Instance */
.il { color: #00BAFF } /* Literal.Number.Integer.Long */

Binary file not shown.

After

Width:  |  Height:  |  Size: 173 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 190 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 B

View File

@@ -0,0 +1,30 @@
[theme]
inherit = basic
stylesheet = default.css
pygments_style = sphinx
[options]
rightsidebar = true
stickysidebar = true
footerbgcolor = #000000
footertextcolor = #ffffff
sidebarbgcolor = #1c4e63
sidebartextcolor = #ffffff
sidebarlinkcolor = #97b9cf
relbarbgcolor = #2C3845
relbartextcolor = #D3E0E9
relbarlinkcolor = #D3E0E9
relbaractlinkcolor = #f39410
bgcolor = #232323
bordercolor = #363636
textcolor = #ffffff
headbgcolor = #232323
headtextcolor = #ffffff
headlinkcolor = #97b9cf
linkcolor = #97b9cf
codebgcolor = #eeffcc
codetextcolor = #333333
bodyfont = "Lucida Grande","Lucida Sans Unicode","Lucida Sans","Lucida",Verdana,sans-serif
headfont = "Lucida Grande","Lucida Sans Unicode","Lucida Sans","Lucida",Verdana,sans-serif

View File

@@ -0,0 +1,132 @@
class IDGroup:
"""
The IDGroup Type
================
This type supports both iteration and the []
operator to get child ID properties.
You can also add new properties using the [] operator.
For example::
group['a float!'] = 0.0
group['an int!'] = 0
group['a string!'] = "hi!"
group['an array!'] = [0, 0, 1.0, 0]
group['a subgroup!] = {"float": 0.0, "an int": 1.0, "an array": [1, 2],
"another subgroup": {"a": 0.0, "str": "bleh"}}
Note that for arrays, the array type defaults to int unless a float is found
while scanning the template list; if any floats are found, then the whole
array is float. Note that double-precision floating point numbers are used for
python-created float ID properties and arrays (though the internal C api does
support single-precision floats, and the python code will read them).
You can also delete properties with the del operator. For example:
del group['property']
To get the type of a property, use the type() operator, for example::
if type(group['bleh']) == str: pass
To tell if the property is a group or array type, import the Blender.Types module and test
against IDGroupType and IDArrayType, like so::
from Blender.Types import IDGroupType, IDArrayType.
if type(group['bleghr']) == IDGroupType:
(do something)
@ivar name: The name of the property
@type name: string
"""
def pop(item):
"""
Pop an item from the group property.
@type item: string
@param item: The item name.
@rtype: can be dict, list, int, float or string.
@return: The removed property.
"""
def update(updatedict):
"""
Updates items in the dict, similar to normal python
dictionary method .update().
@type updatedict: dict
@param updatedict: A dict of simple types to derive updated/new IDProperties from.
@rtype: None
@return: None
"""
def keys():
"""
Returns a list of the keys in this property group.
@rtype: list of strings.
@return: a list of the keys in this property group.
"""
def values():
"""
Returns a list of the values in this property group.
Note that unless a value is itself a property group or an array, you
cannot change it by changing the values in this list, you must change them
in the parent property group.
For example,
group['some_property'] = new_value
. . .is correct, while,
values = group.values()
values[0] = new_value
. . .is wrong.
@rtype: list of strings.
@return: a list of the values in this property group.
"""
def iteritems():
"""
Implements the python dictionary iteritmes method.
For example::
for k, v in group.iteritems():
print "Property name: " + k
print "Property value: " + str(v)
@rtype: an iterator that spits out items of the form [key, value]
@return: an iterator.
"""
def convert_to_pyobject():
"""
Converts the entire property group to a purely python form.
@rtype: dict
@return: A python dictionary representing the property group
"""
class IDArray:
"""
The IDArray Type
================
@ivar type: returns the type of the array, can be either IDP_Int or IDP_Float
"""
def __getitem__(index):
pass
def __setitem__(index, value):
pass
def __len__():
pass

View File

@@ -0,0 +1,45 @@
# Testing the BGL module
import Blender
from Blender.BGL import *
from Blender import Draw
R = G = B = 0
A = 1
instructions = "Hold mouse buttons to change the background color."
quitting = " Press ESC or q to quit."
def show_win():
glClearColor(R,G,B,A) # define color used to clear buffers
glClear(GL_COLOR_BUFFER_BIT) # use it to clear the color buffer
glColor3f(1,1,1) # change default color
glRasterPos2i(50,100) # move cursor to x = 50, y = 100
Draw.Text("Testing BGL + Draw") # draw this text there
glRasterPos2i(350,20) # move cursor again
Draw.Text(instructions + quitting) # draw another msg
glBegin(GL_LINE_LOOP) # begin a vertex-data list
glVertex2i(46,92)
glVertex2i(120,92)
glVertex2i(120,115)
glVertex2i(46,115)
glEnd() # close this list
glColor3f(0.35,0.18,0.92) # change default color again
glBegin(GL_POLYGON) # another list, for a polygon
glVertex2i(315, 292)
glVertex2i(412, 200)
glVertex2i(264, 256)
glEnd()
Draw.Redraw(1) # make changes visible.
def ev(evt, val): # this is a callback for Draw.Register()
global R,G,B,A # it handles input events
if evt == Draw.ESCKEY or evt == Draw.QKEY:
Draw.Exit() # this quits the script
elif evt == Draw.LEFTMOUSE: R = 1 - R
elif evt == Draw.MIDDLEMOUSE: G = 1 - G
elif evt == Draw.RIGHTMOUSE: B = 1 - B
else:
Draw.Register(show_win, ev, None)
Draw.Register(show_win, ev, None) # start the main loop

View File

@@ -0,0 +1,21 @@
"""
Basic Sound Playback
++++++++++++++++++++
This script shows how to use the classes: :class:`Device`, :class:`Factory` and
:class:`Handle`.
"""
import aud
device = aud.device()
# load sound file (it can be a video file with audio)
factory = aud.Factory('music.ogg')
# play the audio, this return a handle to control play/pause
handle = device.play(sound)
# if the audio is not too big and will be used often you can buffer it
factory_buffered = aud.Factory.buffer(sound)
handle_buffered = device.play(buffered)
# stop the sounds (otherwise they play until their ends)
handle.stop()
handle_buffered.stop()

View File

@@ -0,0 +1,37 @@
"""
Basic Physics Constraint
++++++++++++++++++++++
Example of how to create a hinge Physics Constraint between two objects.
"""
from bge import logic
from bge import constraints
# get object list
objects = logic.getCurrentScene().objects
# get object named Object1 and Object 2
object_1 = objects["Object1"]
object_2 = objects["Object2"]
# want to use Edge constraint type
constraint_type = 2
# get Object1 and Object2 physics IDs
physics_id_1 = object_1.getPhysicsId()
physics_id_2 = object_2.getPhysicsId()
# Use bottom right edge of Object1 for hinge position
edge_position_x = 1.0
edge_position_y = 0.0
edge_position_z = -1.0
# use Object1 y axis for angle to point hinge
edge_angle_x = 0.0
edge_angle_y = 1.0
edge_angle_z = 0.0
# create an edge constraint
constraints.createConstraint(physics_id_1, physics_id_2,
constraint_type,
edge_position_x, edge_position_y, edge_position_z,
edge_angle_x, edge_angle_y, edge_angle_z)

View File

@@ -0,0 +1,39 @@
"""
Texture replacement
++++++++++++++++++++++
Example of how to replace a texture in game with an external image.
createTexture() and removeTexture() are to be called from a module Python
Controller.
"""
from bge import logic
from bge import texture
def createTexture(cont):
"""Create a new Dynamic Texture"""
object = cont.owner
# get the reference pointer (ID) of the internal texture
ID = texture.materialID(obj, 'IMoriginal.png')
# create a texture object
object_texture = texture.Texture(object, ID)
# create a new source with an external image
url = logic.expandPath("//newtexture.jpg")
new_source = texture.ImageFFmpeg(url)
# the texture has to be stored in a permanent Python object
logic.texture = object_texture
# update/replace the texture
logic.texture.source = new_source
logic.texture.refresh(False)
def removeTexture(cont):
"""Delete the Dynamic Texture, reversing back the final to its original state."""
try:
del logic.texture
except:
pass

View File

@@ -0,0 +1,32 @@
"""
Basic Video Playback
++++++++++++++++++++++
Example of how to replace a texture in game with a video. It needs to run everyframe
"""
import bge
from bge import texture
from bge import logic
cont = logic.getCurrentController()
obj = cont.owner
# the creation of the texture must be done once: save the
# texture object in an attribute of bge.logic module makes it persistent
if not hasattr(logic, 'video'):
# identify a static texture by name
matID = texture.materialID(obj, 'IMvideo.png')
# create a dynamic texture that will replace the static texture
logic.video = texture.Texture(obj, matID)
# define a source of image for the texture, here a movie
movie = logic.expandPath('//trailer_400p.ogg')
logic.video.source = texture.VideoFFmpeg(movie)
logic.video.source.scale = True
# quick off the movie, but it wont play in the background
logic.video.source.play()
# you need to call this function every frame to ensure update of the texture.
logic.video.refresh(True)

View File

@@ -0,0 +1,44 @@
"""
Hello World Text Example
++++++++++++++++++++++++
Blender Game Engine example of using the blf module. For this module to work we
need to use the OpenGL wrapper :class:`~bgl` as well.
"""
# import game engine modules
from bge import render
from bge import logic
# import stand alone modules
import bgl
import blf
def init():
"""init function - runs once"""
# create a new font object, use external ttf file
font_path = logic.expandPath('//Zeyada.ttf')
# store the font indice - to use later
logic.font_id = blf.load(font_path)
# set the font drawing routine to run every frame
scene = logic.getCurrentScene()
scene.post_draw = [write]
def write():
"""write on screen"""
width = render.getWindowWidth()
height = render.getWindowHeight()
# OpenGL setup
bgl.glMatrixMode(bgl.GL_PROJECTION)
bgl.glLoadIdentity()
bgl.gluOrtho2D(0, width, 0, height)
bgl.glMatrixMode(bgl.GL_MODELVIEW)
bgl.glLoadIdentity()
# BLF drawing routine
font_id = logic.font_id
blf.position(font_id, (width * 0.2), (height * 0.3), 0)
blf.size(font_id, 50, 72)
blf.draw(font_id, "Hello World")

View File

@@ -0,0 +1,27 @@
import bpy
# print all objects
for obj in bpy.data.objects:
print(obj.name)
# print all scene names in a list
print(bpy.data.scenes.keys())
# remove mesh Cube
if "Cube" in bpy.data.meshes:
mesh = bpy.data.meshes["Cube"]
print("removing mesh", mesh)
bpy.data.meshes.remove(mesh)
# write images into a file next to the blend
import os
file = open(os.path.splitext(bpy.data.filepath)[0] + ".txt", 'w')
for image in bpy.data.images:
file.write("%s %d x %d\n" % (image.filepath, image.size[0], image.size[1]))
file.close()

View File

@@ -0,0 +1,22 @@
"""
Execution Context
+++++++++++++++++
When calling an operator you may want to pass the execution context.
This determines the context thats given to the operator to run in, and weather
invoke() is called or execute().
'EXEC_DEFAULT' is used by default but you may want the operator to take user
interaction with 'INVOKE_DEFAULT'.
The execution context is as a non keyword, string argument in:
('INVOKE_DEFAULT', 'INVOKE_REGION_WIN', 'INVOKE_REGION_CHANNELS',
'INVOKE_REGION_PREVIEW', 'INVOKE_AREA', 'INVOKE_SCREEN', 'EXEC_DEFAULT',
'EXEC_REGION_WIN', 'EXEC_REGION_CHANNELS', 'EXEC_REGION_PREVIEW', 'EXEC_AREA',
'EXEC_SCREEN')
"""
# group add popup
import bpy
bpy.ops.object.group_instance_add('INVOKE_DEFAULT')

View File

@@ -0,0 +1,30 @@
"""
Calling Operators
+++++++++++++++++
Provides python access to calling operators, this includes operators written in
C, Python or Macros.
Only keyword arguments can be used to pass operator properties.
Operators don't have return values as you might expect, instead they return a
set() which is made up of: {'RUNNING_MODAL', 'CANCELLED', 'FINISHED',
'PASS_THROUGH'}.
Common return values are {'FINISHED'} and {'CANCELLED'}.
Calling an operator in the wrong context will raise a RuntimeError,
there is a poll() method to avoid this problem.
Note that the operator ID (bl_idname) in this example is 'mesh.subdivide',
'bpy.ops' is just the access path for python.
"""
import bpy
# calling an operator
bpy.ops.mesh.subdivide(number_cuts=3, smoothness=0.5)
# check poll() to avoid exception.
if bpy.ops.object.mode_set.poll():
bpy.ops.object.mode_set(mode='EDIT')

View File

@@ -0,0 +1,31 @@
"""
Operator Example
++++++++++++++++
A common use of custom properties is for python based :class:`Operator` classes.
"""
import bpy
class DialogOperator(bpy.types.Operator):
bl_idname = "object.dialog_operator"
bl_label = "Property Example"
my_float = bpy.props.FloatProperty(name="Some Floating Point")
my_bool = bpy.props.BoolProperty(name="Toggle Option")
my_string = bpy.props.StringProperty(name="String Value")
def execute(self, context):
print("Dialog Runs")
return {'FINISHED'}
def invoke(self, context, event):
wm = context.window_manager
return wm.invoke_props_dialog(self)
bpy.utils.register_class(DialogOperator)
# test call
bpy.ops.object.dialog_operator('INVOKE_DEFAULT')

View File

@@ -0,0 +1,27 @@
"""
PropertyGroup Example
+++++++++++++++++++++
PropertyGroups can be used for collecting custom settings into one value
to avoid many indervidual settings mixed in together.
"""
import bpy
class MaterialSettings(bpy.types.PropertyGroup):
my_int = bpy.props.IntProperty()
my_float = bpy.props.FloatProperty()
my_string = bpy.props.StringProperty()
bpy.utils.register_class(MaterialSettings)
bpy.types.Material.my_settings = \
bpy.props.PointerProperty(type=MaterialSettings)
# test the new settings work
material = bpy.data.materials[0]
material.my_settings.my_int = 5
material.my_settings.my_float = 3.0
material.my_settings.my_string = "Foo"

View File

@@ -0,0 +1,34 @@
"""
Collection Example
++++++++++++++++++
Custom properties can be added to any subclass of an :class:`ID`,
:class:`Bone` and :class:`PoseBone`.
"""
import bpy
# Assign a collection
class SceneSettingItem(bpy.types.PropertyGroup):
name = bpy.props.StringProperty(name="Test Prop", default="Unknown")
value = bpy.props.IntProperty(name="Test Prop", default=22)
bpy.utils.register_class(SceneSettingItem)
bpy.types.Scene.my_settings = \
bpy.props.CollectionProperty(type=SceneSettingItem)
# Assume an armature object selected
print("Adding 3 values!")
my_item = bpy.context.scene.my_settings.add()
my_item.name = "Spam"
my_item.value = 1000
my_item = bpy.context.scene.my_settings.add()
my_item.name = "Eggs"
my_item.value = 30
for my_item in bpy.context.scene.my_settings:
print(my_item.name, my_item.value)

View File

@@ -0,0 +1,21 @@
"""
Update Example
++++++++++++++
It can be useful to perform an action when a property is changed and can be
used to update other properties or synchronize with external data.
All properties define update functions except for CollectionProperty.
"""
import bpy
def update_func(self, context):
print("my test function", self)
bpy.types.Scene.testprop = bpy.props.FloatProperty(update=update_func)
bpy.context.scene.testprop = 11.0
# >>> my test function <bpy_struct, Scene("Scene")>

View File

@@ -0,0 +1,18 @@
"""
Assigning to Existing Classes
+++++++++++++++++++++++++++++
Custom properties can be added to any subclass of an :class:`ID`,
:class:`Bone` and :class:`PoseBone`.
These properties can be animated, accessed by the user interface and python
like blenders existing properties.
"""
import bpy
# Assign a custom property to an existing type.
bpy.types.Material.custom_float = bpy.props.FloatProperty(name="Test Prob")
# Test the property is there.
bpy.data.materials[0].custom_float = 5.0

View File

@@ -0,0 +1,34 @@
import bpy
filepath = "//link_library.blend"
# load a single scene we know the name of.
with bpy.data.libraries.load(filepath) as (data_from, data_to):
data_to.scenes = ["Scene"]
# load all meshes
with bpy.data.libraries.load(filepath) as (data_from, data_to):
data_to.meshes = data_from.meshes
# link all objects starting with 'A'
with bpy.data.libraries.load(filepath, link=True) as (data_from, data_to):
data_to.objects = [name for name in data_from.objects if name.startswith("A")]
# append everything
with bpy.data.libraries.load(filepath) as (data_from, data_to):
for attr in dir(data_to):
setattr(data_to, attr, getattr(data_from, attr))
# the loaded objects can be accessed from 'data_to' outside of the context
# since loading the data replaces the strings for the datablocks or None
# if the datablock could not be loaded.
with bpy.data.libraries.load(filepath) as (data_from, data_to):
data_to.meshes = data_from.meshes
# now operate directly on the loaded data
for mesh in data_to.meshes:
if mesh is not None:
print(mesh.name)

View File

@@ -0,0 +1,19 @@
"""
User Clear
++++++++++
This function is for advanced use only, misuse can crash blender since the user
count is used to prevent data being removed when it is used.
"""
# This example shows what _not_ to do, and will crash blender.
import bpy
# object which is in the scene.
obj = bpy.data.objects["Cube"]
# without this, removal would raise an error.
obj.user_clear()
# runs without an exception
# but will crash on redraw.
bpy.data.objects.remove(obj)

View File

@@ -0,0 +1,37 @@
"""
Submenus
++++++++
This menu demonstrates some different functions.
"""
import bpy
class SubMenu(bpy.types.Menu):
bl_idname = "OBJECT_MT_select_submenu"
bl_label = "Select"
def draw(self, context):
layout = self.layout
layout.operator("object.select_all", text="Select/Deselect All")
layout.operator("object.select_inverse", text="Inverse")
layout.operator("object.select_random", text="Random")
# access this operator as a submenu
layout.operator_menu_enum("object.select_by_type", "type", text="Select All by Type...")
layout.separator()
# expand each operator option into this menu
layout.operator_enum("object.lamp_add", "type")
layout.separator()
# use existing memu
layout.menu("VIEW3D_MT_transform")
bpy.utils.register_class(SubMenu)
# test call to display immediately.
bpy.ops.wm.call_menu(name="OBJECT_MT_select_submenu")

View File

@@ -0,0 +1,17 @@
"""
Extending Menus
+++++++++++++++
When creating menus for addons you can't reference menus in blenders default
scripts.
Instead the addon can add menu items to existing menus.
The function menu_draw acts like Menu.draw
"""
import bpy
def menu_draw(self, context):
self.layout.operator("wm.save_homefile")
bpy.types.INFO_MT_file.append(menu_draw)

View File

@@ -0,0 +1,38 @@
"""
Basic Menu Example
++++++++++++++++++
This script is a simple menu, menus differ from panels in that they must
reference from a header, panel or another menu.
Notice the 'CATEGORY_MT_name' :class:`Menu.bl_idname`, this is a naming
convention for menus.
.. note::
Menu subclasses must be registered before referencing them from blender.
.. note::
Menu's have their :class:`Layout.operator_context` initialized as
'EXEC_REGION_WIN' rather then 'INVOKE_DEFAULT', so if the operator context
needs to initialize inputs from the :class:`Operator.invoke` function
then this needs to be explicitly set.
"""
import bpy
class BasicMenu(bpy.types.Menu):
bl_idname = "OBJECT_MT_select_test"
bl_label = "Select"
def draw(self, context):
layout = self.layout
layout.operator("object.select_all", text="Select/Deselect All")
layout.operator("object.select_inverse", text="Inverse")
layout.operator("object.select_random", text="Random")
bpy.utils.register_class(BasicMenu)
# test call to display immediately.
bpy.ops.wm.call_menu(name="OBJECT_MT_select_test")

View File

@@ -0,0 +1,52 @@
"""
Invoke Function
+++++++++++++++
:class:`Operator.invoke` is used to initialize the operator from the context
at the moment the operator is called.
invoke() is typically used to assign properties which are then used by
execute().
Some operators don't have an execute() function, removing the ability to be
repeated from a script or macro.
This example shows how to define an operator which gets mouse input to
execute a function and that this operator can be invoked or executed from
the python api.
Also notice this operator defines its own properties, these are different
to typical class properties because blender registers them with the
operator, to use as arguments when called, saved for operator undo/redo and
automatically added into the user interface.
"""
import bpy
class SimpleMouseOperator(bpy.types.Operator):
""" This operator shows the mouse location,
this string is used for the tooltip and API docs
"""
bl_idname = "wm.mouse_position"
bl_label = "Invoke Mouse Operator"
x = bpy.props.IntProperty()
y = bpy.props.IntProperty()
def execute(self, context):
# rather then printing, use the report function,
# this way the message appears in the header,
self.report({'INFO'}, "Mouse coords are %d %d" % (self.x, self.y))
return {'FINISHED'}
def invoke(self, context, event):
self.x = event.mouse_x
self.y = event.mouse_y
return self.execute(context)
bpy.utils.register_class(SimpleMouseOperator)
# Test call to the newly defined operator.
# Here we call the operator and invoke it, meaning that the settings are taken
# from the mouse.
bpy.ops.wm.mouse_position('INVOKE_DEFAULT')
# Another test call, this time call execute() directly with pre-defined settings.
bpy.ops.wm.mouse_position('EXEC_DEFAULT', x=20, y=66)

View File

@@ -0,0 +1,51 @@
"""
Calling a File Selector
+++++++++++++++++++++++
This example shows how an operator can use the file selector.
Notice the invoke function calls a window manager method and returns
RUNNING_MODAL, this means the file selector stays open and the operator does not
exit immediately after invoke finishes.
The file selector runs the operator, calling :class:`Operator.execute` when the
user confirms.
The :class:`Operator.poll` function is optional, used to check if the operator
can run.
"""
import bpy
class ExportSomeData(bpy.types.Operator):
"""Test exporter which just writes hello world"""
bl_idname = "export.some_data"
bl_label = "Export Some Data"
filepath = bpy.props.StringProperty(subtype="FILE_PATH")
@classmethod
def poll(cls, context):
return context.object is not None
def execute(self, context):
file = open(self.filepath, 'w')
file.write("Hello World " + context.object.name)
return {'FINISHED'}
def invoke(self, context, event):
context.window_manager.fileselect_add(self)
return {'RUNNING_MODAL'}
# Only needed if you want to add into a dynamic menu
def menu_func(self, context):
self.layout.operator_context = 'INVOKE_DEFAULT'
self.layout.operator(ExportSomeData.bl_idname, text="Text Export Operator")
# Register and add to the file selector
bpy.utils.register_class(ExportSomeData)
bpy.types.INFO_MT_file_export.append(menu_func)
# test call
bpy.ops.export.some_data('INVOKE_DEFAULT')

View File

@@ -0,0 +1,31 @@
"""
Dialog Box
++++++++++
This operator uses its :class:`Operator.invoke` function to call a popup.
"""
import bpy
class DialogOperator(bpy.types.Operator):
bl_idname = "object.dialog_operator"
bl_label = "Simple Dialog Operator"
my_float = bpy.props.FloatProperty(name="Some Floating Point")
my_bool = bpy.props.BoolProperty(name="Toggle Option")
my_string = bpy.props.StringProperty(name="String Value")
def execute(self, context):
message = "Popup Values: %f, %d, '%s'" % \
(self.my_float, self.my_bool, self.my_string)
self.report({'INFO'}, message)
return {'FINISHED'}
def invoke(self, context, event):
wm = context.window_manager
return wm.invoke_props_dialog(self)
bpy.utils.register_class(DialogOperator)
# test call
bpy.ops.object.dialog_operator('INVOKE_DEFAULT')

View File

@@ -0,0 +1,46 @@
"""
Custom Drawing
++++++++++++++
By default operator properties use an automatic user interface layout.
If you need more control you can create your own layout with a
:class:`Operator.draw` function.
This works like the :class:`Panel` and :class:`Menu` draw functions, its used
for dialogs and file selectors.
"""
import bpy
class CustomDrawOperator(bpy.types.Operator):
bl_idname = "object.custom_draw"
bl_label = "Simple Modal Operator"
filepath = bpy.props.StringProperty(subtype="FILE_PATH")
my_float = bpy.props.FloatProperty(name="Float")
my_bool = bpy.props.BoolProperty(name="Toggle Option")
my_string = bpy.props.StringProperty(name="String Value")
def execute(self, context):
print()
return {'FINISHED'}
def invoke(self, context, event):
context.window_manager.fileselect_add(self)
return {'RUNNING_MODAL'}
def draw(self, context):
layout = self.layout
col = layout.column()
col.label(text="Custom Interface!")
row = col.row()
row.prop(self, "my_float")
row.prop(self, "my_bool")
col.prop(self, "my_string")
bpy.utils.register_class(CustomDrawOperator)
# test call
bpy.ops.object.custom_draw('INVOKE_DEFAULT')

View File

@@ -0,0 +1,57 @@
"""
Modal Execution
+++++++++++++++
This operator defines a :class:`Operator.modal` function which running,
handling events until it returns {'FINISHED'} or {'CANCELLED'}.
Grab, Rotate, Scale and Fly-Mode are examples of modal operators.
They are especially useful for interactive tools,
your operator can have its own state where keys toggle options as the operator
runs.
:class:`Operator.invoke` is used to initialize the operator as being by
returning {'RUNNING_MODAL'}, initializing the modal loop.
Notice __init__() and __del__() are declared.
For other operator types they are not useful but for modal operators they will
be called before the :class:`Operator.invoke` and after the operator finishes.
"""
import bpy
class ModalOperator(bpy.types.Operator):
bl_idname = "object.modal_operator"
bl_label = "Simple Modal Operator"
def __init__(self):
print("Start")
def __del__(self):
print("End")
def execute(self, context):
context.object.location.x = self.value / 100.0
def modal(self, context, event):
if event.type == 'MOUSEMOVE': # Apply
self.value = event.mouse_x
self.execute(context)
elif event.type == 'LEFTMOUSE': # Confirm
return {'FINISHED'}
elif event.type in ('RIGHTMOUSE', 'ESC'): # Cancel
return {'CANCELLED'}
return {'RUNNING_MODAL'}
def invoke(self, context, event):
self.value = event.mouse_x
self.execute(context)
print(context.window_manager.modal_handler_add(self))
return {'RUNNING_MODAL'}
bpy.utils.register_class(ModalOperator)
# test call
bpy.ops.object.modal_operator('INVOKE_DEFAULT')

View File

@@ -0,0 +1,27 @@
"""
Basic Operator Example
++++++++++++++++++++++
This script shows simple operator which prints a message.
Since the operator only has an :class:`Operator.execute` function it takes no
user input.
.. note::
Operator subclasses must be registered before accessing them from blender.
"""
import bpy
class HelloWorldOperator(bpy.types.Operator):
bl_idname = "wm.hello_world"
bl_label = "Minimal Operator"
def execute(self, context):
print("Hello World")
return {'FINISHED'}
bpy.utils.register_class(SimpleOperator)
# test call to the newly defined operator
bpy.ops.wm.hello_world()

View File

@@ -0,0 +1,43 @@
"""
Simple Object Panel
+++++++++++++++++++
This panel has a :class:`Panel.poll` and :class:`Panel.draw_header` function,
even though the contents is basic this closely resemples blenders panels.
"""
import bpy
class ObjectSelectPanel(bpy.types.Panel):
bl_idname = "OBJECT_PT_select"
bl_label = "Select"
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "object"
bl_options = {'DEFAULT_CLOSED'}
@classmethod
def poll(cls, context):
return (context.object is not None)
def draw_header(self, context):
layout = self.layout
obj = context.object
layout.prop(obj, "select", text="")
def draw(self, context):
layout = self.layout
obj = context.object
row = layout.row()
row.prop(obj, "hide_select")
row.prop(obj, "hide_render")
box = layout.box()
box.label("Selection Tools")
box.operator("object.select_all")
row = box.row()
row.operator("object.select_inverse")
row.operator("object.select_random")
bpy.utils.register_class(ObjectSelectPanel)

View File

@@ -0,0 +1,36 @@
"""
Mix-in Classes
++++++++++++++
A mix-in parent class can be used to share common properties and
:class:`Menu.poll` function.
"""
import bpy
class View3DPanel():
bl_space_type = 'VIEW_3D'
bl_region_type = 'TOOLS'
@classmethod
def poll(cls, context):
return (context.object is not None)
class PanelOne(View3DPanel, bpy.types.Panel):
bl_idname = "VIEW3D_PT_test_1"
bl_label = "Panel One"
def draw(self, context):
self.layout.label("Small Class")
class PanelTwo(View3DPanel, bpy.types.Panel):
bl_idname = "VIEW3D_PT_test_2"
bl_label = "Panel Two"
def draw(self, context):
self.layout.label("Also Small Class")
bpy.utils.register_class(PanelOne)
bpy.utils.register_class(PanelTwo)

View File

@@ -0,0 +1,28 @@
"""
Basic Panel Example
+++++++++++++++++++
This script is a simple panel which will draw into the object properties
section.
Notice the 'CATEGORY_PT_name' :class:`Panel.bl_idname`, this is a naming
convention for panels.
.. note::
Panel subclasses must be registered for blender to use them.
"""
import bpy
class HelloWorldPanel(bpy.types.Panel):
bl_idname = "OBJECT_PT_hello_world"
bl_label = "Hello World"
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "object"
def draw(self, context):
self.layout.label(text="Hello World")
bpy.utils.register_class(HelloWorldPanel)

View File

@@ -0,0 +1,40 @@
"""
Custom Properties
+++++++++++++++++
PropertyGroups are the base class for dynamically defined sets of properties.
They can be used to extend existing blender data with your own types which can
be animated, accessed from the user interface and from python.
.. note::
The values assigned to blender data are saved to disk but the class
definitions are not, this means whenever you load blender the class needs
to be registered too.
This is best done by creating an addon which loads on startup and registers
your properties.
.. note::
PropertyGroups must be registered before assigning them to blender data.
.. seealso::
Property types used in class declarations are all in :mod:`bpy.props`
"""
import bpy
class MyPropertyGroup(bpy.types.PropertyGroup):
custom_1 = bpy.props.FloatProperty(name="My Float")
custom_2 = bpy.props.IntProperty(name="My Int")
bpy.utils.register_class(MyPropertyGroup)
bpy.types.Object.my_prop_grp = bpy.props.PointerProperty(type=MyPropertyGroup)
# test this worked
bpy.data.objects[0].my_prop_grp.custom_1 = 22.0

View File

@@ -0,0 +1,70 @@
"""
Simple Render Engine
++++++++++++++++++++
"""
import bpy
class CustomRenderEngine(bpy.types.RenderEngine):
# These three members are used by blender to set up the
# RenderEngine; define its internal name, visible name and capabilities.
bl_idname = 'custom_renderer'
bl_label = 'Flat Color Renderer'
bl_use_preview = True
# This is the only method called by blender, in this example
# we use it to detect preview rendering and call the implementation
# in another method.
def render(self, scene):
scale = scene.render.resolution_percentage / 100.0
self.size_x = int(scene.render.resolution_x * scale)
self.size_y = int(scene.render.resolution_y * scale)
if scene.name == 'preview':
self.render_preview(scene)
else:
self.render_scene(scene)
# In this example, we fill the preview renders with a flat green color.
def render_preview(self, scene):
pixel_count = self.size_x * self.size_y
# The framebuffer is defined as a list of pixels, each pixel
# itself being a list of R,G,B,A values
green_rect = [[0.0, 1.0, 0.0, 1.0]] * pixel_count
# Here we write the pixel values to the RenderResult
result = self.begin_result(0, 0, self.size_x, self.size_y)
layer = result.layers[0]
layer.rect = green_rect
self.end_result(result)
# In this example, we fill the full renders with a flat blue color.
def render_scene(self, scene):
pixel_count = self.size_x * self.size_y
# The framebuffer is defined as a list of pixels, each pixel
# itself being a list of R,G,B,A values
blue_rect = [[0.0, 0.0, 1.0, 1.0]] * pixel_count
# Here we write the pixel values to the RenderResult
result = self.begin_result(0, 0, self.size_x, self.size_y)
layer = result.layers[0]
layer.rect = blue_rect
self.end_result(result)
# Register the RenderEngine
bpy.utils.register_class(CustomRenderEngine)
# RenderEngines also need to tell UI Panels that they are compatible
# Otherwise most of the UI will be empty when the engine is selected.
# In this example, we need to see the main render image button and
# the material preview panel.
from bl_ui import properties_render
properties_render.RENDER_PT_render.COMPAT_ENGINES.add('custom_renderer')
del properties_render
from bl_ui import properties_material
properties_material.MATERIAL_PT_preview.COMPAT_ENGINES.add('custom_renderer')
del properties_material

View File

@@ -0,0 +1,28 @@
"""
Note that when keying data paths which contain nested properties this must be
done from the :class:`ID` subclass, in this case the :class:`Armature` rather
then the bone.
"""
import bpy
from bpy.props import PointerProperty
# define a nested property
class MyPropGroup(bpy.types.PropertyGroup):
nested = bpy.props.FloatProperty(name="Nested", default=0.0)
# register it so its available for all bones
bpy.utils.register_class(MyPropGroup)
bpy.types.Bone.my_prop = PointerProperty(type=MyPropGroup,
name="MyProp")
# get a bone
obj = bpy.data.objects["Armature"]
arm = obj.data
# set the keyframe at frame 1
arm.bones["Bone"].my_prop_group.nested = 10
arm.keyframe_insert(data_path='bones["Bone"].my_prop.nested',
frame=1,
group="Nested Group")

View File

@@ -0,0 +1,11 @@
"""
This is the most simple example of inserting a keyframe from python.
"""
import bpy
obj = bpy.context.object
# set the keyframe at frame 1
obj.location = 3.0, 4.0, 10.0
obj.keyframe_insert(data_path="location", frame=1)

View File

@@ -0,0 +1,3 @@
import mathutils
# todo

View File

@@ -0,0 +1,3 @@
import mathutils
# todo

View File

@@ -0,0 +1,3 @@
import mathutils
# todo

View File

@@ -0,0 +1,56 @@
import mathutils
# zero length vector
vec = mathutils.Vector((0.0, 0.0, 1.0))
# unit length vector
vec_a = vec.copy().normalize()
vec_b = mathutils.Vector((0.0, 1.0, 2.0))
vec2d = mathutils.Vector((1.0, 2.0))
vec3d = mathutils.Vector((1.0, 0.0, 0.0))
vec4d = vec_a.to_4d()
# other mathutuls types
quat = mathutils.Quaternion()
matrix = mathutils.Matrix()
# Comparison operators can be done on Vector classes:
# greater and less then test vector length.
vec_a > vec_b
vec_a >= vec_b
vec_a < vec_b
vec_a <= vec_b
# ==, != test vector values e.g. 1,2,3 != 3,2,1 even if they are the same length
vec_a == vec_b
vec_a != vec_b
# Math can be performed on Vector classes
vec_a + vec_b
vec_a - vec_b
vec_a * vec_b
vec_a * 10.0
matrix * vec_a
quat * vec_a
vec_a * vec_b
-vec_a
# You can access a vector object like a sequence
x = vec_a[0]
len(vec)
vec_a[:] = vec_b
vec_a[:] = 1.0, 2.0, 3.0
vec2d[:] = vec3d[:2]
# Vectors support 'swizzle' operations
# See http://en.wikipedia.org/wiki/Swizzling_(computer_graphics)
vec.xyz = vec.zyx
vec.xy = vec4d.zw
vec.xyz = vec4d.wzz
vec4d.wxyz = vec.yxyx

Some files were not shown because too many files have changed in this diff Show More